[03] 节点流和处理流


1、节点流和处理流的概念

根据输入输出方式不同,我们划分了输入流和输出流;根据处理数据流的单位不同,我们划分了字节流和字符流;现在我们根据数据封装类型的不同划分节点流和处理流。

  • 节点流
  • 如果流封装的是某种特定的数据源,如文件、字符串、字符串数组等,则称为节点流

  • 处理流
  • 如果流封装的是其他的流对象,称之为处理流。处理流提供缓冲功能,提高读写效率

2、节点流和处理流的常用类

节点流中常用类
  • 字节输入流 FileInputStream
  • 字节输出流 FileOutputStream
  • 字符输入流 FileReader
  • 字符输出流 FileWriter

处理流中常用类
  • 缓冲字节输出流 BufferedOutputStream
  • 缓冲字节输入流 BufferedInputStream
  • 缓冲字符输入流 BufferedReader
  • 缓冲字符输出流 BufferedWriter

这里所谓的缓冲:就是对操作的数据进行了临时的缓存,从而提高读写的效率。

这样的描述可能不太容易理解,引用一段《Head First Java》中的描述,缓冲区类似超市里的购物推车:
使用缓冲区比没有使用的效率更高,实际上你确实可以直接使用FileWriter,调用write()来写文件,就像你在超市购物,你每拿一样东西就跑去收银台付一次账,如果没有像超市推车一样的缓冲区,你确实也能达到目的,但也累得不行,效率还很低

而我们常说的flush(),实际上就是强制缓冲区立即写入,形象地说,就是马上把推车推到收银台去结一次账

好了,这样你就一定能形象地理解缓冲的好处了,下面聊聊处理流的特点
  • 字符缓冲输入流提供了读取一行的方法readLine()
  • 字符缓冲输出流提供了写入一个空行的方法newLine()
  • 字符缓冲输出流,把写入的数据先写入到内存,再使用flush()方法将内存数据刷到硬盘上

需要注意的是,在使用close()关闭流之前,一定要先flush()一下,避免数据的丢失。离开超市之前不结账,你觉得最后能把东西拿回家吗?

3、示例

3.1 示例代码

我们以读取硬盘上某个txt文本中的信息并写入到另一个文件为例,假如在电脑桌面有文件test.txt,内容如下:
这是一个简单的测试用的文本文件
这是第二行了
笑嘻嘻地敲下第三行,我觉得差不多了

我们要读取该文件内容并同样复写到另一个文件temp.txt中,则代码为:
public static void main(String[] args) {  

    //创建副本
    File temp = new File("C:\Users\Dulk\Desktop\temp.txt");
    if (!temp.exists()) {
        try {
            temp.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //读取源文件
    File file = new File("C:\Users\Dulk\Desktop\test.txt");
    if (file.exists()) {
        FileReader reader = null;
        BufferedReader bufferedReader = null;
        FileWriter writer = null;
        BufferedWriter bufferedWriter = null;

        try {
            reader = new FileReader(file);
            bufferedReader = new BufferedReader(reader);

            writer = new FileWriter(temp);
            bufferedWriter = new BufferedWriter(writer);

            String line = bufferedReader.readLine();
            while (line != null) {
                System.out.println(line);
                //数据写入
                bufferedWriter.write(line + "
");
                line = bufferedReader.readLine();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedWriter != null) {
                    //刷新和关闭
                    bufferedWriter.flush();
                    bufferedWriter.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

}

3.2 注意事项

  • read方法每执行一次会移动文件指针,文件末尾时返回-1,不要将read方法直接放在循环中作为判断避免多次移动指针
  • 在new一个FileWriter时,也可以增加一个参数true,表示不覆盖只是增加内容,如 new FileWriter(file, true);
  • 写入文本中换行有两种方式,第一种调用newLine方法新建空行;第二种在增加转义字符,win中使用 " ",linux下使用 " "


原文地址:https://www.cnblogs.com/deng-cc/p/7462325.html