Java-IO流之BufferedReader 和BufferedWriter的使用和原理
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的使用和原理的更多相关文章
- Java IO流学习总结四:缓冲流-BufferedReader、BufferedWriter
在上一篇文章中Java IO流学习总结三:缓冲流-BufferedInputStream.BufferedOutputStream介绍了缓冲流中的字节流,而这一篇着重介绍缓冲流中字符流Buffered ...
- Java:IO流与文件基础
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Java IO流学习总结
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Java IO流题库
一. 填空题 Java IO流可以分为 节点流 和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...
- Java IO流总结
Java IO流分类以及主要使用方式如下: IO流 |--字节流 |--字节输入流 InputStream: int read();//一次读取一个字节 int read(byte[] bys);// ...
- Java IO流详尽解析
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- JAVA.IO流学习笔记
一.java.io 的描述 通过数据流.序列化和文件系统提供系统输入和输出.IO流用来处理设备之间的数据传输 二.流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数 ...
- 【Java基础】Java IO流的总结
Java IO流分为输入流和输出流,而输入流和输出流中又分字符流和字节流.顾名思义,输入流则是输入到程序中计算,输出流是把程序的结果输出到文件或者设备.而字符流输入输出以字符为单位,字节流则是以字节为 ...
随机推荐
- git的操作集合
一.git 操作 $ git branch -a //查看远程分支$ git branch //查看本地分支 $ git branch -d <BranchName>//删除本地分支$ g ...
- 在vscode中使用eslint+prettier格式化vue项目代码 (转载)
ESlint:javascript代码检测工具,可以配置每次保存时格式化js,但每次保存只格式化一点点,你得连续按住Ctrl+S好几次,才格式化好,自行体会~~ vetur:可以格式化html.标准c ...
- LeetCode第十五题-找出数组中三数和为0的答案
3Sum 问题简介: 给定n个整数的数组nums,是否有元素a,b,c在nums中,使a + b + c = 0? 找到数组中所有唯一的三元组,它们的总和为零 注:解决方案集不得包含重复的三元组 例如 ...
- python制作串口工具
# coding:utf-8import timeimport serialimport stringimport binasciiimport linecache FilePath="G: ...
- shell的进度条【转】
生成进度条的俩个shell脚本 !/bin/bash i= bar='' index= arr=( "|" "/" "-" "\\ ...
- git rejected - non-fast-forward
di第一次提交时可能提示此错误,应该是.gitignore冲突,建议码云创建时不要初始化,如果已经出现了.可以从git repostitory里合并. 参考:https://blog.csdn.ne ...
- proxy ubunta
/etc/environment : Is the correct place to specify system-wide environment variables that should be ...
- 二十三种设计模式之原型模式的C#实现
原型模式就是通过拷贝快速创建一个新的对象 本例UML如图 ColorBase [Serializable] public abstract class ColorBase { public int R ...
- Django Rest framework Swagger生成api文档
关于swagger Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因: - Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API. ...
- 解决vuecli3.0构建的vue2.0项目在IE9可能出现的兼容性问题
1,unit8Array等未定义问题 解决办法 <1>npm install @babel/polyfill <2>分别在main.js和vuex的主文件 import '@b ...