Logo

郎哥编程

缓存输入输出流

2019-12-29 106

BufferedInputStream为带缓存的输入流,BufferedOutputStream为带缓存的输出流。缓存输入输出就是在读写磁盘文件之前,先把数据读取或写入到预先分配的内存区域(这片内存区域称为缓冲区),当缓冲区存储的数据已满时,再进行磁盘文件的读写操作。通过缓冲区读写文件带来的好处是可以优化程序的输入输出性能,提供程序读写磁盘文件的速度。

BufferedInputStream类的工作依赖于InputStream,它需要使用InputStream类进行磁盘文件的读写。BufferedInputStream读取文件的工作原理如下图所示:

image.png          

                                    

BufferedInputStream读取文件的工作原理

BufferedInputStream类在内部维护一个缓冲区。实例化BufferedInputStream对象时,需要传入InputStream的实例化对象,当程序调用BufferedInputStream对象从文件读取数据时,它会先判断缓冲区是否有读取的文件数据,如果有就从缓冲区读取,否则就调用InputStream对象从文件读取数据填满缓冲区。

BufferedOutputStream类和BufferedInputStream类的工作原理是相同的,只不过一个是写入文件数据,一个是读取文件数据。BufferedOutputStream类在内部也维护一个缓冲区,当程序调用BufferedOutputStream将数据写入文件时,它会先把数据写入缓冲区,当缓冲区已满时,再调用OutputStream将缓冲区的数据写入到文件。BufferedOutputStream类也提供了flush()方法,可以强制将缓冲区的数据写入到文件。

1、BufferedInputStream类

BufferedInputStream类有默认的缓冲区空间,程序可以在类的构造函数中传入需要的缓冲区空间大小。

BufferedInputStream类的构造函数如下:

●   public BufferedInputStream(InputStream in);

该构造函数创建具有默认缓冲区空间的输入流。

●   public BufferedInputStream(InputStream in, int size);

该构造函数创建指定缓冲区空间大小的输入流。

InputStream类是BufferedInputStream的父类,因此InputStream类定义的方法,BufferedInputStream都可以使用。

案例1:建立BufferedInputStreamTest测试类,读取图片文件。

在PCoreUnit6项目新建buffer包,在buffer包下新建BufferedInputStreamTest类。代码如下:

package buffer;
 
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
 
/** 
* @ClassName: BufferedInputStreamTest 
* @Description: 输入与输出(缓存输入输出流)案例1
* @author 编程训练营 
* @date 
* 
*/
 
public class BufferedInputStreamTest {
 
    /**
     * @Title: main
     * @Description: Java程序入口main方法
     * @param @param args 参数
     *
     * @return void 返回类型 @throws
     */
 
    public static void main(String[] args) {
      
       // 读取的图片文件路径
       String filename = "d:\\001.png";
       BufferedInputStream bufferedInput = null;
       // 申请读取文件的缓冲区
       byte[] buffer = new byte[1024];
 
       try {
 
           // 创建BufferedInputStream 对象
           bufferedInput = new BufferedInputStream(new FileInputStream(filename));
 
           int bytesRead = 0;
 
           // 从文件中按字节读取内容,到文件尾部时read方法将返回-1
           while ((bytesRead = bufferedInput.read(buffer)) != -1) {
 
              // 将读取的字节转为字符串对象
              String content = new String(buffer, 0, bytesRead);
              System.out.print(content);
           }
 
       } catch (FileNotFoundException ex) {
           ex.printStackTrace();
       } catch (IOException ex) {
           ex.printStackTrace();
       } finally {
           // 关闭 BufferedInputStream
           try {
              if (bufferedInput != null)
                  bufferedInput.close();
           } catch (IOException ex) {
               ex.printStackTrace();
           }
       }
 
    }
 
}

案例代码完成读取图片文件的操作,使用BufferedInputStream类的read方法将图片文件数据读入到buffer缓冲区,并将buffer缓冲区的输出到控制台。因为读取的图片文件是二进制文件,所以在控制台显示的是乱码。关闭文件放到了finally语句块,这样做的好处是不管是否发生文件读取异常,都会关闭已打开的文件资源。

程序执行结果如下图所示:

image.png

2、BufferedOutputStream类

BufferedOutputStream类有默认的缓冲区空间,程序可以在类的构造函数中传入需要的缓冲区空间大小。BufferedOutputStream类的构造函数如下:

●   public  BufferedOutputStream(OutputStream out);

该构造函数创建具有默认缓冲区空间的输出流。

●   BufferedOutputStream(OutputStream out, int size);

该构造函数创建指定缓冲区空间大小的输出流。

OutputStream类是BufferedOutputStream的父类,因此OutputStream类定义的方法,BufferedOutputStream都可以使用。

案例2:建立BufferedOutputStreamTest测试类,建立一个二进制文件,输出数据到新建的二进制文件。

在buffer包下新建BufferedOutputStreamTest类。代码如下:

package buffer;
 
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
/** 
* @ClassName: BufferedOutputStreamTest 
* @Description: 输入与输出(缓存输入输出流)案例2
* @author 编程训练营 
* @date 
* 
*/
 
public class BufferedOutputStreamTest {
 
    /** 
    * @Title: main 
    * @Description: Java程序入口main方法
    * @param @param args    参数 
   
    * @return void    返回类型 
    * @throws 
    */
 
    public static void main(String[] args) {
       // TODO Auto-generated method stub
       BufferedOutputStream bufferoutput = null;
       //写数据  
       try {
           bufferoutput = new BufferedOutputStream(new FileOutputStream("d:\\outtest.dat")) ;
           // 将String对象的内容转换为字节数组,并写入文件
           bufferoutput.write("这是一个二进制文件".getBytes());
           System.out.println("文件创建成功");
       } catch (IOException e) {
           // TODO Auto-generated catch block
           System.out.println("文件创建失败");
           e.printStackTrace();
       } finally {
          //释放资源   
          try {
           bufferoutput.close();
       } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
      }
      
    }
 
}

案例代码创建一个二进制文件,并写入字符串对象的内容。虽然创建的是二进制文件,但使用记事本仍然可以看到写入的中文内容,因为新建的二进制文件存储的是中文内容的文字编码。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论