博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IO 流之字符流的缓冲区
阅读量:7088 次
发布时间:2019-06-28

本文共 4722 字,大约阅读时间需要 15 分钟。

  1. 缓冲区的出现提高了对数据的读写效率
  2. 对应类:
    1. BufferedWriter
    2. BufferedReader
  3. 缓冲区需要结合流才可以使用, 对流的功能进行了增强, 即对流的操作起到装饰作用

使用缓冲区实现文本文件的写入和读取

// 写入public class BufferedWriterDemo{    public static void main(String[] args) throws IOException {        FileWriter fw = new FileWriter("buf.txt");        // 为了提高写入的效率, 使用了字符流的缓冲区        // 创建了一个字符写入流的缓冲对象, 并和指定要被缓冲的流对象相关联        BufferedWriter bufw = new BufferedWriter(fw);        // 使用缓冲区的写入方法将数据写入到缓冲区中        bufw.write("abcde");        // 换行, 其实就是封装了系统属性  line.separator        // BufferedWriter 特有方法        bufw.newLine();        bufw.newline("hahaha");        // 使用缓冲区的刷新方法将数据刷入到目的地中        bufw.flush();        // 关闭缓冲区, 其实关闭的就是被缓冲的流对象        bufw.close();    }}// 读取public class BufferedReaderDemo {    public static void main(String[] args){        FileReader fr = new FileReader("buf.txt");        BufferedReader bufr = new BufferedReader();        /*  读取字符数组的方式         *         *  char[] buf = new char[1024];         *  int len = 0;         *  while((len=bufr.read(buf))!= -1){         *  System.out.println(new String(buf,0,len));         *  }         */         // 按一行读取, BufferredReader 特有方法: readLine()         // 如果到达流末尾, 返回 null         String line = null;         while((line=bufr.readLine()) != null){  // 注意: 此处判断的是 != null            System.out.println(line);        }        // 关闭缓冲区        bufr.close();    }}

BufferedReader 中的 readLine() 方法原理

  • BufferedReader 类复写了父类的以下方法:
    • read(); : 读取单个字符
    • read(char[] buf, int off, int len); : 读取数组的一部分
  • BufferedReader 类自己特有的方法 readLine()
  • BufferedReader 类继承了父类方法:
    • read(char[] buf) : 将字符读入数组

1222878-20170911101907250-414923698.png

readLine() 方法原理: 使用了读取缓冲区的 read() 方法, 将读取到的字符进行缓冲并判断换行标记. 将标记前的缓存数据变成字符返回.

模拟实现 BufferedReader

// 需求: 自定义的读取缓冲区, 其实就是模拟一个 BufferedReader/* 分析: *    缓冲区中无非就是封装了一个数组, 并对外提供了更多的方法对数组进行访问 *    其实这些方法最终操作的都是数组的角标 * *     缓冲区原理: 其实就是从源中获取一批数据装进缓冲区中, 在从缓冲区中不断 *     的取出一个一个数据. *      *     在缓冲区中数据此次取完后, 在从源中继续取一批数据进缓冲区, 当源中的数据取光时, *     用 -1 作为结束标记 */ public class MyBufferedReader{    private FileReader r;    // 定义一个数组作为缓冲区    private char[] buf = new char[1024];    // 定义一个指针用于操作这个数组中的元素, 当操作到最后一个元素时, 指针应该归 0    private int pos = 0;    // 定义一个计数器, 记录缓冲区中的数据个数. 当该数据减到0, 就从源中继续获取数据到缓冲区中    private int count = 0;    // 带参数的构造函数, 指定增强的流对象    public MyBufferedReader(FileReader r){        this.r = r;    }    // 定义从缓冲区读取单个字符的 read() 方法    public int myRead() throws IOException{        // 1. 从源中获取一批数据到缓冲区中, 需要先做判断, 只有计数器为 0 时, 才需要从源中获取数据        /* if(count == 0){         *   // 记录从源中获取的数据个数         *   count = r.read(buf);         *   if(count < 0){         *      return -1;         *  }         *  // 每次从源中获取数据到缓冲区后, 角标归零         *   pos = 0;         *   // 获取第一个数据         *   char ch = buf[pos];         *   pos++;         *   count--;         *   return ch;         *   } else {         *   char ch = buf[pos];         *   pos++;         *   count--;         *   return ch;         *   }         */        // 代码优化:        if(count == 0){            count = r.read(buf);            pos = 0;        }        if(count < 0){            return -1;        }        char ch = buf[pos++];        count--;        return ch;    }    // 定义从缓冲区读取一行字符的 readLine() 方法    public String myReadLine() throws IOException{        // 定义一个数组容器, 存储从缓冲区中获取到的数据        StringBuilder sb = new StringBuilder();        // 使用自定义的 MyRead 方法, 从缓冲区中不断获取单个字符,        int ch = 0;        while((ch=myRead()) != -1){            if(ch=='\r')                continue;            if(ch=='\n')                return sb.toString();            // 将从缓冲区中读到的字符, 存储到缓存行数据的缓冲区中            sb.append((char)ch);        }        // 如果最后一行结尾没有回车符, 缓冲区的读取已结束,        // 但是并不能判断 if(ch=='\n'), 所有最后一行未能输出        if(sb.length() != 0)            return sb.toString();        return null;    }    public void myClose() throws IOException{        r.close();    }    }

使用缓冲区的方式复制文本文件

public class CopyTextByBufTest {    public static void main(String[] args) throws IOException {        FileReader fr = new FileReader("buf.txt");        BufferedReader bufr = new BufferedReader(fr);        FileWriter fw = new FileWriter("buf_copy.txt");        BufferedWriter bufw = new BufferedWriter(fw);        /*         *  int ch = 0;         *  // 使用缓冲区对象进行单个字符的读写         *  // 这是直接从内存中读取单个字符, 不是从硬盘中         *  while((ch=bufr.read()) != -1){         *        bufw.write(ch);         *    }         */         // 使用行进行读取文件         String line = null;         while((line=bufr.readLine())!=null){            bufw.write(line);            bufw.newLine();            bufw.flush();  // 注意: 每次写入之后, 进行刷新保存        }        bufw.close();        bufr.close();}}

LineNumberReader 装饰类

  1. BufferedReader 的子类
  2. 可以跟踪行号的缓冲字符输入流
    • setLineNumber(int); : 设置当前行号
    • getLineNumber(); : 获取当前行号

参考资料

转载于:https://www.cnblogs.com/linkworld/p/7503698.html

你可能感兴趣的文章
mac python3 轻松安装教程
查看>>
死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)
查看>>
如何隐藏 shortcut bar
查看>>
LeetCode 448 Find All Numbers Disappeared in an Array
查看>>
css-position
查看>>
iOS应用签名(上)
查看>>
有趣的border-radius
查看>>
Ubuntu远程Windows
查看>>
Zilliqa生态构建资助计划第三批获奖名单
查看>>
javaSE基础知识 1.1代码注释
查看>>
分享一些 Broadcast 使用技巧
查看>>
Flutter audioplayers使用小结
查看>>
iOS 状态栏的图标
查看>>
如何利用Redis实现延时处理
查看>>
我的python之路01(持续更新中........)
查看>>
应届生想要获取web前端开发岗位?这份技能攻略,面试攻略别错过!
查看>>
如何为Apache Kylin快速开发新数据源?
查看>>
简单解读高阶函数和纯函数
查看>>
深入剖析Vue源码 - 数据代理,关联子父组件
查看>>
阿里VS华为-开源镜像站体验及评测
查看>>