JAVA IO流

一. 字节流

1.计算机中都是二进制数据,一个字节是82进制位.字节可以表示所有的数据,比如文本,音频,视频.图片,都是作为字节存在的.也就是说字节流处理的数据非常多。在文本文件中存储的数据是以我们能读懂的方式表示的。而在二进制文件中存储的数据是用二进制形式表示的。我们是读不懂二进制文件的,因为二进制文件是为了让程序来读取而设计的。例如,Java的源程序(.java源文件)存储在文本文件中,可以使用文本编辑器阅读,但是Java的类(字节码文件)存储在二进制文件中,可以被Java虚拟机阅读。二进制文件的优势在于它的处理效率比文本文件高。

    2.输入字节流:

      --------| InputStream 所有输入字节流的基类 抽象类

             ------------| FileInputStream 读取文件数据的输入字节流

                              ------------| FilterInputStream

                                ---------- –-----| BufferedInputStream 缓冲输入字节流 缓冲输入字节流的出现主要是为了提高读取文件数据的效率。 其实该类内部只不过是维护了一个8kb的字节数组而已。

     2.1  使用FileInputStream读取文件数据的步骤:

        1. 找到目标文件

        2. 建立数据的输入通道。

        3. 读取文件中的数据。

        4. 关闭 资源.

    2.1.1 使用read()方法一次读取一个字节

      import java.io.BufferedInputStream;
      import java.io.BufferedOutputStream;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.FileReader;
      import java.io.FileWriter;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.io.OutputStreamWriter;
      public class ioTest {
        public static void main(String [] args) throws IOException {
            FileInputStream fis = new FileInputStream("/home/coolboy/test");
              int len = 0;
              while((len=fis.read())!=-1){
                  System.out.println((char)len);
                }
            }
          }
    2.1.2 
使用read(byte[] b) 方法。

      使用缓冲区(关键是缓冲区大小的确定)使用read方法的时候,流需要读一次就处理一次,可以将读到的数据装入到字节数组中,一次性的操作数组,可以提高效率。

    为了避免缓冲字符数组太小造成数据读取不完,一般建议将缓冲字符数组的大小定义为1024的倍数

      FileInputStream fis = new FileInputStream("/home/coolboy/test");
          byte[] byt = new byte[1024];
          int len = fis.read(byt);
          for(int i = 0 ;i<len ;i++)
              System.out.println((char)byt[i]);
        }

 

 

    发现:一旦数据超过1024个字节,数组就存储不下。

 

    如何将文件的剩余内容读完?

        我们可以通过通过循环保证文件读取完。

        FileInputStream fis = new FileInputStream(path);

          byte[] byt = newbyte[1024];

          int len = 0;

        while ((len = fis.read(byt)) != -1) {

          System.out.println(new String(byt, 0, len));

        }

 

 

    2.2 输入字节缓冲流
      
上述程序中我们为了提高流的使用效率,自定义了字节数组,作为缓冲区.Java其实提供了专门的字节流缓冲来提高效率.BufferedInputStream类可以通过减少读写次数来提高输入和输出的速度。它们内部有一个缓冲区,用来提高处理效率。查看API文档,发现可以指定缓冲区的大小。其实内部也是封装了字节数组。没有指定缓冲区大小,默认的字节是8192显然缓冲区输入流和缓冲区输出流要配合使用。首先缓冲区输入流会将读取到的数据读入缓冲区,当缓冲区满时,或者调用flush方法,缓冲输出流会将数据写出。

 

      注意:当然使用缓冲流来进行提高效率时,对于小文件可能看不到性能的提升。但是文件稍微大一些的话,就可以看到实质的性能提升了。

    FileInputStream fis = new FileInputStream("/home/coolboy/test");
    BufferedInputStream bi = new BufferedInputStream(fis);
      int len = 0;
      while((len=bi.read())!=-1){
          System.out.println((char)len);
       }

 

 

 

  3.输出字节流

 

    --------| OutputStream 是所有输出字节流 的父类。 抽象类

 

      -----------| FileOutStream 向文件输出数据的输出字节流。

      -------| FiterOutputStream

 

          ------------| BufferedOutputstream 缓冲输出字节流 BufferedOutputStream出现的目的是为了提高写数据的效率。内部也是维护了一个8kb的字节数组而已。

 

     3.1 FileOutputStream

        1. 找到目标文件

        2. 建立数据的输出通道。

        3. 把数据转换成字节数组写出。

        4. 关闭资源

        FileOutputStream fos = new FileOutputStream("/home/coolboy/test",true);
            int len = 0;
            byte [] buffer = "123hahaha".getBytes();
              fos.write(buffer);

            fos.close();
            }

     3.2 输出缓冲字节流 BufferedOutputStream

      注:BufferedOutputStream 要注意的细节

      1. 使用BufferedOutStream写数据的时候,它的write方法是是先把数据写到它内部维护的字节数组中。

      2.如果需要把数据真正的写到硬盘上面,需要调用flush方法或者是close方法、 或者是内部维护的字节数组已经填满数据的时候。

      3. 使用FileOutputStream写数据的时候,调用完write()方法就把数据写到硬盘上了;

        FileInputStream fis = new FileInputStream("/home/coolboy/1.jpg");
            FileOutputStream fos = new FileOutputStream("/home/coolboy/a/1.jpg");
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            int len = 0;
            while((len=bis.read())!=-1){
                bos.write(len);
            }
            bis.close();
            bos.close();
            }

二.字符流  

计算机并不区分二进制文件与文本文件。所有的文件都是以二进制形式来存储的,因此,从本质上说,所有的文件都是二进制文件。所以字符流是建立在字节流之上的,它能够提供字符层次的编码和解码。例如,在写入一个字符时,Java虚拟机会将字符转为文件指定的编码(默认是系统默认编码),在读取字符时,再将文件指定的编码转化为字符。

字符流 = 字节流+编码/解码

例如:使用GBK将中文保存在计算机中“中国”,其中中文占用两个字节,如果使用字节流进行输出时会显示乱码,我们的FileInputStream输入流的read() 一次是读一个字节的,

使用:"中国".getBytes() 即可得到字符串对应的字节数组,是[-42, -48, -71, -6],那么中国对应的是-42, -48, -71, -64个字节。那就是一个中文占2个字节,(这个

和编码是有关系的)很显然,我们的中文就不能够再一个字节一个字节的读了。

 

 

 

 

 

 

 

 

 

 

    

    输入字符流:

      ---------| Reader 所有输入字符流的基类。 抽象类。

      ----------|java.io.InputStreamReader

          ----------------| FileReader 读取文件数据的输入字符流。 (是转换流的子类)

      ----------------| BufferedReader 缓冲输入字符流,该类出现的目的是为了提高读取文件数据的效率与 拓展FileReader(readLine)功能。 这个类的也只不过是在内部维护了一个8kb的字符数组而已。

      Reader reader = new FileReader(path);

        int len = 0;

      while ((len = reader.read()) != -1) {

      System.out.print((char) len);

      }


      reader.close();

    }


输出字符流:

---------| Writer 所有输出字符流的基类。 抽象类

----------------| FileWriter 向文件输出数据的输出字符流 (是转换流的子类)

----------------| BufferedWriter 缓冲输出字符流,该类出现的目的是为了提高写文件数据的效率与 拓展FileWriter(newLine)功能.newLine() 换行。

 

 

 

 

 

 

 

 

 

 

posted on 2018-04-20 14:29  孤独的电影  阅读(89)  评论(0)    收藏  举报