• [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下使用 " "


  • 相关阅读:
    LeetCode数学系列(3)——快速幂算法(50题)
    LeetCode树系列(3)——200题岛屿数量
    Arrays.sort()详解
    图表示学习系列(1)——GCN学习笔记:第一部分,详细讲解GCN
    LeetCode动态规划系列(3)——编辑距离问题求解
    深度学习系列(9)——node2vec算法中的alias采样介绍
    LeetCode数学系列(2)——解决约瑟夫问题
    Java数据结构系列(4)——队列常用方法
    LeetCode树系列(1)——广度搜索应用,图的BFS
    LeetCode树系列(2)——深度搜索运用:LeetCode695题详解
  • 原文地址:https://www.cnblogs.com/deng-cc/p/7462325.html
Copyright © 2020-2023  润新知