欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

程序员文章站 2024-03-07 08:06:02
...

I/O流概述:


结构:

Java中的I/O流主要定义在java.io包中,该包下定义了很多类,其中有4个类为流的*类,分别为InputStream和OutputStream,Reader和Writer。

说明:

InputStream和OutPutStream是字节流,而Reader和Writer是字符流;
InputStream和Reader是输入流,而OutPutStream和Writer是输出流;
图中的4个*类都是抽象类,并且是所有流类型的父类。

图示:

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)


字节流概述:


定义:

在计算机中,无论是文本、图片、音频还是视频,所有文件都是以二进制(字节)形式存在的,I/O流中针对字节的输入/输出提供了一系列的流,统称为字节流。

说明:

字节流是程序中最常用的流。
在JDK中,所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。

InputStream与OutputStream示意图:

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

说明:

InputStream被看成一个输入管道,OutputStream被看成一个输出管道,数据通过InputStream从源设备输入到程序,通过OutputStream从程序输出到目标设备,从而实现数据的传输。

InputStream的常用方法:

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

说明:

前三个read()方法都是用来读数据的,分按字节读取和按字节数组读取。
进行I/O流操作时,应该调用close()方法关闭流,从而释放当前I/O流所占的系统资源。

OutputStream的常用方法:

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

说明:

前三个write()方法都是用来写数据的,分按字节读取和按字节数组写入。
flush()方法用来将当前输出流缓冲区(通常是字节数组)中的数据强制写入目标设备,此过程称为刷新。
close()方法是用来关闭流并释放与当前IO流相关的系统资源。

InputStream与OutputStream的继承体系:

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)


字节流读写文件:


说明:

针对文件的读写操作,JDK专门提供了两个类,分别是FileInputStream和FileOutputStream。
FileInputStream是InputStream的子类,它是操作文件的字节输入流,专门用于读取文件中的数据。
从文件读取数据是重复的操作,因此需要通过循环语句来实现数据的持续读取。

示例(读取包含“hello”内容的txt文件):

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)
注意:上面的结果返回的是每个字符的ASSIC码值。

示例(向txt文件写入数据):

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

注意:

通过FileOutputStream向一个已经存在的文件中写入数据,该文件中的数据首先会被清空,再写入新的数据。若希望在已存在的文件内容之后追加新内容,则可使用构造函数FileOutputStream(String fileName, boolean append)来创建文件输出流对象,并把append参数的值设置为true。

示例(向txt文件写入数据):

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

注意:

I/O流在进行数据读写操作时会出现异常,为了保证I/O流的close()方法一定执行来释放占用的系统资源,通常会将关闭流的操作写在finally代码块中。

 finally{
          try{
                if(in!=null)       in.close();
          }catch(Exception e){
 e.printStackTrace();
          }
          try{
 if(out!=null)     out.close();
          }catch(Exception e){
 e.printStackTrace();
          }
    }

文件的拷贝


说明:

I/O流通常都是成对出现的,即输入流和输出流一起使用。例如文件的拷贝就需要通过输入流来读取源文件中的数据,并通过输出流将数据写入新文件。

    FileInputStream in = new FileInputStream("source/src.jpg");
    FileOutputStream out = new FileOutputStream("target/dest.jpg");
    int len = 0;
    long beginTime = System.currentTimeMillis();
    while ((len = in.read()) != -1) {   
            out.write(len);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
    in.close();
    out.close();

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)


字节流的缓冲区:


假设从北京运送快递到上海,如果有一万件
快递,一件一件的运送就必须运输一万次,这样
的效率显然非常低。为了减少运输次数,可以先
把一批快递装在一个车厢中,这样就可以成批的运送快递,这时的车厢就相当于一个临时缓冲区。

同理:在文件拷贝过程中,通过以字节形式逐个拷贝,效率也非常低。为此,可以定义一个字节数组缓冲区,在拷贝文件时,就可以一次性读取多个字节的数据

示例(使用字节流缓冲区拷贝文件):

  FileInputStream in = new FileInputStream("source/src.jpg");
    FileOutputStream out = new FileOutputStream("target/dest.jpg");
    int len = 0;
    byte[] buff = new byte[1024];
    long beginTime = System.currentTimeMillis();
    while ((len = in.read(buff)) != -1) {
          out.write(buff,0,len);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
    in.close();
    out.close();

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

说明:

从图可以看出拷贝文件所消耗的时间明显减少了很多,这说明使用缓冲区读写文件可以有效的提高程序的传输效率。
程序中的缓冲区就是一块内存,该内存主要用于存放暂时输入/输出的数据,由于使用缓冲区减少了对文件的操作次数,所以可以提高读写数据的效率。


字节缓冲流:


说明:

除了定义字节缓冲区来提高文件拷贝效率外,IO中还提供了两个字节缓冲流来提高文件拷贝效率:BufferedInputStream和BufferedOutputStream。它们的构造方法中分别接收InputStream和OutputStream类型的参数作为对象,在读写数据时提供缓冲功能。

缓冲流示意图:

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)


示例(使用字节缓冲流拷贝文件):


 BufferedInputStream bis = new BufferedInputStream(
    new FileInputStream("source/src.jpg"));
    BufferedOutputStream bos = new BufferedOutputStream(
                   new FileOutputStream("target/dest.jpg"));
    int len = 0;
    long beginTime = System.currentTimeMillis();
    while ((bis.read()) != -1) {
            bos.write(len);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
    bis.close();
    bos.close();

图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

说明:

从图可以看出拷贝文件所消耗的时间明显减少了很多,这说明使用字节缓冲流同样可以有效的提高程序的传输效率。
这种方式与字节流的缓冲区类似,都对数据进行了缓冲,从而有效的提高了数据的读写效率。


多加补充:


InputStream是所有字节输入流的抽象基类
图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)
OutputStream是所有字节输出流的父类
图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)
FileInputStream是文件的字节输入流,使用该流可以以字节为单位从文件中读取数据
图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)
FileOutputStream是文件的字节输出流,我们可以以字节为单位将数据写入文件
图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)
可以向已经存在的文件中追加内容的构造方法
图文精讲(一)——Java中I/O流——字节流(概述、读写文件、文件的拷贝、缓冲区、缓冲流)

相关标签: Java2020上