IO流及缓冲流

1 IO流

1.1 IO流分类

流向分类
   输入输出
文件操作处理单元分类
   字节流和字符流

FileInputStream
   文件操作输入字节流
FileOutputStream
   文件操作输出字节流

FileReader
   文件操作输入字符流
FileWriter
   文件操作输出字符流


1.2 文件操作字节流

1.2.1 文件操作输入字节流

FileInputStream 文件操作输入字节流

Constructor 构造方法
   FileInputStream(File file);
      这里是根据提供的File类对象创建对应的文件操作输入字节流。

   FileInputStream(String pathName);
      这里是根据提供的String类型文件路径,创建对应的文件操作输入字节流。
   都会抛出异常:
   FileNotFoundException 文件未找到异常。

Method 成员方法
   int read();
      从文件中读取一个字节数据返回到方法外。
      虽然返回值是一个int类型,但是在整个int类型当中存储的数据是一个byte类型,有且只有低8位数据有效

   int read(byte[] buf);
      读取文件的内容是存储在byte类型数组中,返回值是读取到的字节个数

   int read(byte[] buf, int offset, int count);
      读取文件的内容是存储在byte类型数组中,要求从byte数组offset位置开始,到count长度结束,返回值是读取到的字节个数

   以上三个方法如果读取到文件末尾,返回值都是 -1 EOF End Of File
   而且以上方法都要异常抛出
      IOException IO异常


1.2.2 文件读取使用缓冲和非缓冲差距

内存的运作速度看做是火箭
硬盘就是一个自行车
    固态硬盘,4KB对齐。固态硬盘中每一个扇区都是4KB。如果缓冲这里是要求CPU读取两个4KB数据,对于CPU而言没有太多压力。

    如果是一个字节一个字节读取,CPU取出4KB数据,结果有4095无效。

1.2.3 文件操作输出字节流

fileOutputStream 文件操作输出字节流

Constructor 构造方法
    FileOutputStream(File file);
        根据File类对象创建对应的文件输出字节流对象
    FileOutputStream(String pathName);
        根据String类型文件路径创建对应的文件输出字节流对象

    以上两个构造方法,创建的FileOutputStream是删除写/清空写操作,会将原文件中的内容全部删除之后,写入数据。

    FileOutputStream(File file, boolean append);
        根据File类对象创建对应的文件输出字节流对象。创建对象时给予append参数为true,表示追加写。
    FileOutputStream(String pathName, boolean append);
        根据String类型文件路径创建对应的文件输出字节流对象,创建对象时给予append参数为true,表示追加写。

    FileOutputStream构造方法是拥有创建文件的内容,如果文件存在,不创建,文件不存在且路径正确,创建对应文件。否则抛出异常FileNotFoundException
Method 成员方法
    void write(int b);
        写入一个字节数据到当前文件中,参数是int类型,但是有且只会操作对应的低八位数据
    void write(byte[] buf);
        写入字节数组中的内容到文件中
    void write(byte[] buf, int offset, int length);
        写入字节数组中的内容到文件中,从指定的offset开始,到指定长度length

以上方法会抛出异常:IOException**

1.3 文件操作字符流

1.3.1 字符流特征

字符流 = 字节流 + 解码过程
   字节组合操作 ==> 对应当前环境编码集的一个字符
   如果字符找不到,该数据无效,需要被删除。

如果是字符内容操作,效率还可以!!!
如果是非字符操作,凶多吉少!!!

字符流操作文件
   个人建议,该文件可以使用notepad 记事本打开无乱码,可以使用字符流操作。
   视频文件,图片文件,特定格式的文件,都无法使用字符操作。


1.3.2 文件操作输入字符流

FileReader 文件操作输入字符流

Constructor 构造方法
   FileReader(File file)
      根据File类对象创建对应的FileReader字符流输入对象
   FileReader(String pathName)
      根据String类型文件路径创建对应的FileReader字符流输入对象
   如果文件不存在,抛出异常FileNotFoundException

Method 成员方法
   int read();
      读取文件中的一个字符数据,通过返回值返回,返回值类型是int类型,但是在int类型中有且只有低16位数据有效
   int read(char[] arr);
      读取文件中的数据保存到字符数组中,返回值类型是读取到的字符个数
   int read(char[] arr, int off, int len);
      读取文件中的数据保存到字符数组中,要求从数组中下标offset开始,到len结束,返回值类型是读取到的字符个数

以上方法,如果读取到文件默认,返回值为-1 EOF End Of File
如果读取操作工作中,出现问题,抛出异常IOException


1.4 文件操作字符输出流

FileWriter文件操作输出字符流

Constructor 构造方法
   FileWriter(File file);
      根据File类对象创建对应文件的文件操作输出字符流
   FileWriter(String pathName);
      根据String类型文件路径创建对应文件的文件操作输出字符流
   FileWriter(File file, boolean append);
      根据File类对象创建对应文件的文件操作输出字符流,并要求为追加
   FileWriter(String pathName, boolean append);
      根据String类型文件路径创建对应文件的文件操作输出字符流,并要求为追加写

   如果创建FileWrite对象时,这里文件不存在,路径合法,这里会创建对应的操作文件。如果路径不合法,抛出异常 FileNotFoundException

Method 成员方法
   void write(int ch);
      写入一个char类型数据到文件中
   void write(char[] arr);
      写入一个char类型数组到文件中
   void write(char[] arr, int offset, int length);
      写入一个char类型数组到文件中,要求从offset下标位置开始读取数组数据,长度为length
   void write(String str);
      写入一个字符串到文件中
   void write(String str, int offset, int lenght);
      写入一个字符串到文件中,要求从指定字符串offset下标位置开始,长度为length
   如果写入数据操作过程中,发生问题,这里会有一个IOException


2. 缓冲流

2.1 缓冲流有什么作用

使用缓冲数组以后,整体的读取,写入效率提升很大!!!
降低了CPU通过内存访问硬盘的次数。提高效率,降低磁盘损耗。

字节输入缓冲
   BufferedInputStream
字节输出缓冲
   BufferedOutputStream
字符输入缓冲
   BufferedReader
字符输出缓冲
   BufferedWrite

【重点】
所有的缓冲流都没有任何的读取,写入文件能力,这里都需要对应的输入流和输出流来提供对应的能力。
在创建缓冲流流对象时,需要传入对应的输入流对象和输出流对象。
底层就是提供了一个默认大小的缓冲数组,用于提高效率


2.2 字节缓冲流

输入
   BufferedInputStream(InputStream in);
      这里需要的对象是一个字节输入流基类对象。同时也可也传入InputStream子类对象
输出
   BufferedOutputStream(OutputStream out);
      这里需要的对象是一个字节输出流基类对象。同时也可也传入OutputStream子类对象
以上传入的InputStream和OutputStream都是用于提供对应文件的读写能力。


2.2.1 字节输入流缓冲效率问题

1. 在BufferedInputStream底层中有一个默认容量为8KB的byte类型缓冲数组
2. fill方法是一个操作核心
   a. 从硬盘中读取数据,读取的数据容量和缓冲数组容量一致。
   b. 所有的read方法,都是从缓冲数组中读取数据
   c. 每一次读取数据之前,都会检查缓冲区内是否有数据,如果没有,fill方法执行,填充数据。

3. 利用缓冲,fill方法,可以极大的降低CPU通过内存访问硬盘的次数。同时程序操作的数据是在内存中进行交互的。

2.2.2 字节输出流缓冲效率问题

1. 在BufferedOutputStream类对象,默认有一个8KB的byte类型缓冲数组
2. 数据写入文件时并不是直接保存到文件中,而是保存在内存8KB字节缓冲数组中
3. 如果8KB空间填满,会直接flush缓冲区,数据保存到硬盘中,同时清空整个缓冲区。
4. 在BufferedOutputStream关闭时,首先会调用flush方法,保存数据到文件,清空缓冲区,并且归还缓冲区占用内存,同时关闭缓冲流使用的字节输出流。


2.3 字符缓冲流

BufferedReader
   字符缓冲输入流
   BufferedReader(Reader reader);
BufferedWriter
   字符缓冲输出流
   BufferedWriter(Writer writer);


2.3.1 字符缓冲流效率问题

1. 字符缓冲输入流,底层有一个8192个元素的缓冲字符数组,而且使用fill方法从硬盘中读取数据填充缓冲数组
2. 字符缓冲输出流,底层有一个8192个元素的缓冲字符数组,使用flush方法将缓冲数组中的内容写入到硬盘当中。
3. 使用缓冲数组之后,程序在运行的大部分时间内都是内存和内存直接的数据交互过程。内存直接的操作效率是比较高的。并且降低了CPU通过内存操作硬盘的次数
4. 关闭字符缓冲流,都会首先释放对应的缓冲数组空间,并且关闭创建对应的字符输入流和字符输出流。
5.
字符缓冲输入流中
String readLine(); 读取一行数据
字符缓冲输出流中
void newLine(); 换行

发布了6 篇原创文章 · 获赞 14 · 访问量 830

猜你喜欢

转载自blog.csdn.net/weixin_44945658/article/details/104541996