zoukankan      html  css  js  c++  java
  • Java IO 流(一)

    字节流和字符流

    字节流InputStream/OutputStream ,只能操作byte
    字符流Reader/Writer

    节点流和过滤流

    节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
    过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。FliterInputStream、FliterOutputStream

     

    FileoutputStream(File f)

    字节流本身是只能操作byte的。
    对于这一个类,如果文件不存在会自动创建
    write()方法默认会将文件进行覆盖
    可以使用构造方法FileoutputStream(File f,boolean append),这样就可以指定要不要使用追加模式

    FileinputStream(File f)

    方法 - available() 获得可以读取的字节数

    字符流

    一般一个字符为两个字节,可以直接操作字符串
    会用到缓冲区
    FileWriter/FileReader
    默认依然是覆盖,要追加只要和FileoutputStream类似加boolean标志就好了 Filereader读取到char/char[]

    字节流和字符流的不同

    字节流是直接与文件操作,不会用到缓冲区 字符流数据先放在缓冲区,然后再从缓冲区写到文件,要记得fiush()或者close()

    字节-字符的转换流

    1. InputStreamReader
      将一个输入字节流转为字符流,是Reader的子类
    2. OutputStreamWriter
      将一个输出字节流转为字符流,是Writer的子类

    FileWriter是OutputStreamWriter的子类 FileReader是OutputStreamReader的子类

    内存操作流

    ByteArrayInputStream(byte[])
    将byte中是数据写入内存中
    ByteArrayOutputStream()
    实际的意思就是说,通过输入流将数据写入到内存里面,然后通过输出流把内存里面的东西取出来!

        private static void tesByteArrayInputStream() {
        // 创建ByteArrayInputStream字节流,内容是ArrayLetters数组
        ByteArrayInputStream bais = new ByteArrayInputStream(ArrayLetters);
    
        // 从字节流中读取5个字节
        for (int i=0; i<LEN; i++) {
            // 若能继续读取下一个字节,则读取下一个字节
            if (bais.available() >= 0) {
                // 读取“字节流的下一个字节”
                int tmp = bais.read();
                System.out.printf("%d : 0x%s
    ", i, Integer.toHexString(tmp));
            }
        }
    
        // 若“该字节流”不支持标记功能,则直接退出
        if (!bais.markSupported()) {
            System.out.println("make not supported!");
            return ;
        }
    
        // 标记“字节流中下一个被读取的位置”。即--标记“0x66”,因为因为前面已经读取了5个字节,所以下一个被读取的位置是第6个字节”
        // (01), ByteArrayInputStream类的mark(0)函数中的“参数0”是没有实际意义的。
        // (02), mark()与reset()是配套的,reset()会将“字节流中下一个被读取的位置”重置为“mark()中所保存的位置”
        bais.mark(0);
    
        // 跳过5个字节。跳过5个字节后,字节流中下一个被读取的值应该是“0x6B”。
        bais.skip(5);
    
        // 从字节流中读取5个数据。即读取“0x6B, 0x6C, 0x6D, 0x6E, 0x6F”
        byte[] buf = new byte[LEN];
        bais.read(buf, 0, LEN);
        // 将buf转换为String字符串。“0x6B, 0x6C, 0x6D, 0x6E, 0x6F”对应字符是“klmno”
        String str1 = new String(buf);
        System.out.printf("str1=%s
    ", str1);
    
        // 重置“字节流”:即,将“字节流中下一个被读取的位置”重置到“mark()所标记的位置”,即0x66。
        bais.reset();
        // 从“重置后的字节流”中读取5个字节到buf中。即读取“0x66, 0x67, 0x68, 0x69, 0x6A”
        bais.read(buf, 0, LEN);
        // 将buf转换为String字符串。“0x66, 0x67, 0x68, 0x69, 0x6A”对应字符是“fghij”
        String str2 = new String(buf);
        System.out.printf("str2=%s
    ", str2);
    }
    

    }

    管道流

    管道流就是实现两个进程之间的通信

    PipeOutputStream PipeInputStream 使用的时候要使用connect()把输入输出流连接起来,Connect是PipeOutputStream的方法,用来连接一个PipeInputStream

    打印流

    PrintStream

    定义了很多的print和pringtln方法,可以打印任意数据类型
    System.out就是定位在输出设备的PrintStream

    构造方法,指定输出的位置
    PrintSTream(OutputStream out)
    

    这样打印输出更加方便了,PrintStream就是OutputStream的子类,可以方便的进行输出,这样的设计称之为装饰设计模式

    PrintWriter与上面的类似

    格式化输出

    类似于C语言的格式化输出 %d,%s,%f,%c

    ps.printf("姓名%s,年龄:%d",a,b);
    

    System.in以及BufferedReader(字符流)

    是一个InputStream

        BufferedReader buf=null;
        buf=new BufferedReader(new InputStreamReader(System.in));
        String str=null;
        try {
            while ((str=buf.readLine())!=null){
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    

    输入输出重定向

    System.setOut(new PrintStream(new FileOutputStream("D:/a.txt")));
    

    实际上in、out、err就是System的三个常量,可以通过set方法改变,然后就完成了重定向的作用。

    Scanner

    在java.util包中,可以实现BufferedReader的全部功能,是一个工具类

    • 默认的分隔符是空格,可以自行设置
    • 非常强大,可以接受多种类型的数据,但是对于日期类型没有支持,可以使用Scanner.hasNext(Pattern)/next(Pattern)匹配来取出数据
    • 可以接受File,做一系列文件操作

      Scanner scanner=new Scanner(System.in);
      scanner.useDelimiter("
      ");//修改分割符
      int a=0;
      float f=0f;
      String date=null;
      
      if(scanner.hasNextInt()){
          a=scanner.nextInt();
      }
      if(scanner.hasNextFloat()){
          f=scanner.nextFloat();
      }
      if(scanner.hasNext("\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}")){
          date=scanner.next("\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}");
      }
      System.out.println(a+" "+f+" "+date);
      try {
          Date date1=new SimpleDateFormat("yy-MM-dd hh:mm:ss").parse(date);
          System.out.println(date1);
      } catch (ParseException e) {
          e.printStackTrace();
      }
      

    合并流

    压缩流

    支持三种格式的压缩,zip/jar/Gzip,这里以zip为例另外两种都是一样的
    ZipEntry,就是压缩文件目录下的每一个文件

    • ZipOutputStream(OutputStream)
      • PutNextEntry(ZipEntry ?)

    可以将文件、文件夹进行压缩

    ZipFile类

    专门表示压缩文件的类

    回退流

    字符编码

    获得本机编码
    System.getProperity("file.encoding")
    

    常见的编码格式

    • iso8859-1单字节编码,只能表示英文
    • GBK国标,表示汉字
    • unicode 16进制两个字节的编码,最标准的,但是不兼容iso-8859-1
    • utf 变长的编码,一个字符长度1--6不等,可以表示所有语言的字符、

    关于io流的结构

    输入流

    • InputStream
      • ByteArrayInputStream(byte[])
      • FileInputStream(File)
      • PipedInputStream
      • SequenceInputStream(InputStream,InputStream)
      • FilterInputStream
        • BufferedInputStream(InputStream)
        • PushbackInputStream
        • DataInputStream
          • ObjectInputStream

    输出流

    • OutputStream
      • ByteArrayOutputStream
      • FileOutputStream
      • PipedOutputStream
      • FilterOutputStream
        • BufferedOutputStream
        • PrintWriter
        • DataOutputStream
          • ObjectOutputStream

    常见的方法

                            InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:
    
                          1   public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。
    
                          2   public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
    
                          3   public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
    
                          4   public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
    
                          5   public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
    
                          6   public int close( ) :我们在使用完后,必须对我们打开的流进行关闭. 
    
                        OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
    
                          1. public void write(byte b[ ]):将参数b中的字节写到输出流。
    
                          2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
    
                          3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
    
                          4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
    
                          5. public void close( ) : 关闭输出流并释放与流相关的系统资源。
    

    java的流类提供了结构化方法,如,底层流和高层过滤流。
    而高层流不是从输入设备读取,而是从其他流读取。同样高层输出流也不是写入输出设备,而是写入其他流。
    使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为Decorator
    Pattern。Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得
    decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。这也是Java I/O
    类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类

    • DataInputStream 包含了一整套读取primitive数据的接口
    • BufferedInputStream,为InputStream增加了一个缓冲区,缓冲区的大小是8k
    • PushbackInputStream 有一个"弹压单字节"的缓冲区,可以把最后读到的那个字节再压回去
    • DataOutputStream 包括写入primitive数据的全套接口。
    • PrintStream(inpurstream,boolean autoflush) 打印流
    • BufferedOutputStream 有缓冲区
  • 相关阅读:
    Eclipse的SVN插件与本地SVN客户端关联不上
    Oracle与MySQL连接配置
    树莓派实践项目
    20135333苏正生——信息安全系统设计基础第十四周学习总结
    《图解tcp/ip》读书笔记(二)
    解决VC几个编译问题的方法——好用
    《深入理解计算机系统》深入实践之——vim深入研究
    20135333苏正生——信息安全系统设计基础第十二周学习总结
    《图解tcp/ip》读书笔记(一)
    《你的灯亮着吗?:发现问题的真正所在》读书笔记2
  • 原文地址:https://www.cnblogs.com/Coder-Pig/p/6599120.html
Copyright © 2011-2022 走看看