BufferedReader和BufferedWriter出现的目的是为了对FileReader以及FileWriter的读写操作进行增强,而怎么增强呢,原理类似于使用StringBuilder,是把数据先放入他们的一个char数组中,然后再操作char数组。

使用缓冲区的字符流是使用了装饰着模式对FileReader等进行功能上的增强,装饰者模式与继承都可以实现功能上的增强,但是装饰者可以做得更加的灵活,也不会使继承树变得太过复杂。

以下是BufferedWriter源码的一小部分

public class BufferedReader extends Reader {

    private Reader in;  构造函数需要用到的Reader

    private char cb[];   自己的char数组,它本身的read()方法将是访问这个数组,这个数组就是缓冲区
private int nChars, nextChar; char数组位置和数量的索引

接下来看一下BufferedWriter源码的read()方法:

    public int read() throws IOException {
synchronized (lock) {
ensureOpen();
for (;;) {
if (nextChar >= nChars) {
fill();
if (nextChar >= nChars)
return -1;
}
if (skipLF) {
skipLF = false;
if (cb[nextChar] == '\n') {
nextChar++;
continue;
}
}
return cb[nextChar++];
}
}
}

这个read()方法是访问的BufferedReader本身的char数组,当发现数组的元素已经被访问完毕就调用fill()方法重新填充char数组。这个就是使用缓冲区的字符流的实质。

同样的,BufferedWriter也是先把数据写入自身的char数组中,刷新的时候再写入文件。

注意:

1、当使用BufferedWriter或者是BufferedReader的时候,是把FileReader的赋给了BufferedReader里面的Reader对象,所以要保存数据到文件的时候调用传入BufferedReader的参数Reader是无效的,需要使用BufferedReader进行刷新或者关BufferedReader之后数据才会保存到文件;

2、当关闭BufferedReader的时候,传入作为参数的reader也会跟着关闭。

3、BufferedReader具有一个特殊的方法readerLine(),功能是读取一行,原理是从char数组中读取,判断是否遇到换行符,是的话返回。

下面有根据传智播客的IO视频自己写的一个BufferedReader代码:

public class MyBufferedReader {

    private Reader reader;

    private int count;
private int position;
private char[] contentArray = new char[1024];
private int ch; private final String LINE_SEPARATE = System.getProperty("line.separate"); public MyBufferedReader(Reader reader) {
this.reader = reader;
} public int myReader() throws IOException {
if (count == 0) {
count = reader.read(contentArray);
position = 0;
} if (count == -1) {
return -1;
} count--;
ch = contentArray[position];
position++; return ch;
} public String myReadLine() throws IOException {
StringBuilder sb = new StringBuilder(256);
int ch = 0;
while ((ch = myReader()) != -1) {
if (ch == '\r') {
continue;
} if ((char) ch == '\n') {
return sb.toString();
} sb.append((char) ch);
} if (sb.length() > 0)
return sb.toString(); return null;
} public void close() throws IOException {
reader.close();
} }

  这里是调用的代码:

        try (FileWriter fileWriter = new FileWriter("buffer.txt")) {
try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
int count = 3; while (count != 0) {
bufferedWriter.write("123456");
bufferedWriter.newLine();
bufferedWriter.write("abcdef");
bufferedWriter.newLine();
count--;
}
}
} try (FileReader fileReader = new FileReader("buffer.txt")) {
MyBufferedReader bufferedReader = new MyBufferedReader(fileReader);
String line = null;
while ((line = bufferedReader.myReadLine()) != null) {
System.out.println(line);
}
}

  运行结果为:

Disconnected from the target VM, address: '127.0.0.1:26416', transport: 'socket'
123456
abcdef
123456
abcdef
123456
abcdef Process finished with exit code 0

  

Java-IO流之BufferedReader 和BufferedWriter的使用和原理的更多相关文章

  1. Java IO流学习总结四:缓冲流-BufferedReader、BufferedWriter

    在上一篇文章中Java IO流学习总结三:缓冲流-BufferedInputStream.BufferedOutputStream介绍了缓冲流中的字节流,而这一篇着重介绍缓冲流中字符流Buffered ...

  2. Java:IO流与文件基础

    Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...

  3. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  4. Java IO流学习总结

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  5. Java IO流题库

    一.    填空题 Java IO流可以分为   节点流   和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...

  6. Java IO流总结

    Java IO流分类以及主要使用方式如下: IO流 |--字节流 |--字节输入流 InputStream: int read();//一次读取一个字节 int read(byte[] bys);// ...

  7. Java IO流详尽解析

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  8. JAVA.IO流学习笔记

    一.java.io 的描述 通过数据流.序列化和文件系统提供系统输入和输出.IO流用来处理设备之间的数据传输 二.流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数 ...

  9. 【Java基础】Java IO流的总结

    Java IO流分为输入流和输出流,而输入流和输出流中又分字符流和字节流.顾名思义,输入流则是输入到程序中计算,输出流是把程序的结果输出到文件或者设备.而字符流输入输出以字符为单位,字节流则是以字节为 ...

随机推荐

  1. 二值化神经网络(BNN)基础学习(一)

    目录 1.简介 2.优点 3.基本原理 3.1 权重和激活值二值化[3] 3.2 乘法优化 3.3 权重和激活值更新 4.结论[3] 参考资料 1.简介 ​ 二值化神经网络,在浮点型(权重值和激活函数 ...

  2. django-auth组件

    auth组件 一.auth模块简介 auth模块是django自带的用户认证模块,包含了身份验证和权限管理两部分. 身份验证用于核实某个用户是否合法,权限管理用于决定一个合法用户有哪些权限 默认情况下 ...

  3. vertx模块HAManager高可用

    HAManager public HAManager(VertxInternal vertx, DeploymentManager deploymentManager, ClusterManager ...

  4. cpu-z笔记本加条子

    前天:给笔记本升级能升级的东西就两个,一个内存条,一个光驱换固态硬盘,我说下升级内存 1.先将自己笔记本的型号上中关村在线查下自己的笔记本型号最大能支持多大的内存扩容 中关村在线网站:http://n ...

  5. 客户端和浏览器都不能连接SVN服务器

    错误提示 1.在对话框中提示 2.在As上提示 Error:svn: E731001: Unable to connect to a repository at URL 'https://XXX/sv ...

  6. 使用Postman测试https接口时的小问题记录

    测试本地的WebApi接口时,接口是https,自己写的用httpclient测试是可以的, 用postman一直连接不了.原因正是由于https,不过postman在界面上已经给出了可能的原因和解决 ...

  7. mysql 两例习题

    一. 综述:两张表,一张顾客信息表customers,一张订单表orders .创建一张顾客信息表customers,字段要求如下: c_id 类型为整型,设置为主键,并设置为自增长属性 c_name ...

  8. 使用X509Certificate2类操作证书文件

    public class CertHelper { string pfxPath = @"E:\开发辅助项目\cert\taisuyuanqing.pfx"; string cer ...

  9. HttpListener 实现web服务器

    一.使用方法 1. Start()方法 允许此实例接受传入的请求.即开始监听 2. Stop()方法 处理完所有当前排队的请求后关闭HttpListener对象 3. GetContext()方法  ...

  10. SQL 将变量定义为Table类型

    ),a2 ,),a4 DATETIME,a5 UNIQUEIDENTIFIER) ,11.22,GETDATE(),NEWID()) ,11.22,GETDATE(),NEWID()) ,11.22, ...