一、简介

  设计ReaderWriter继承层次结构主要是为了国际化。InputStreamOutStream流继承层次结构仅支持8位字节流,并不能很好的处理16位的Unicode字符。由于Unicode用于字符国际化(java本身的char也是16位的Unicode),所以添加了Reader和Writer继承层次结构就是为了所有的I/O操作中都支持Unicode。另外,字符流(Reader、Writer)比字节流(InputSteam、OutStream)更快。

  Reader 和 Writer对于字符流的输入和输出也是作为协议的存在。

二、Reader(输入)

  基本和InputStream差不多,只不过它是操作字符流的。

public abstract class Reader implements Readable, Closeable {

    //为了提高效率,字流对象可以使用除自身之外的对象来保护临界段。因此,子类应该在这个字段中使用对象,而不是this或同步方法。
protected Object lock; protected Reader() {
this.lock = this;
} protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
} //
public int read(java.nio.CharBuffer target) throws IOException {
int len = target.remaining();
char[] cbuf = new char[len];
int n = read(cbuf, 0, len);
if (n > 0)
target.put(cbuf, 0, n);
return n;
} //读取单个字符
public int read() throws IOException {
char cb[] = new char[1];
if (read(cb, 0, 1) == -1)
return -1;
else
return cb[0];
} //将字符读入数组
public int read(char cbuf[]) throws IOException {
return read(cbuf, 0, cbuf.length);
} //从off开始,读取len长度的数组,读入数组中
abstract public int read(char cbuf[], int off, int len) throws IOException; //可跳过字符数量的最大值
private static final int maxSkipBufferSize = 8192; //存储跳过的字符数组
private char skipBuffer[] = null; //跳过字符。返回实际跳过的字符数
public long skip(long n) throws IOException {
if (n < 0L)
throw new IllegalArgumentException("skip value is negative");
int nn = (int) Math.min(n, maxSkipBufferSize); //获取最小值
synchronized (lock) { //加锁
if ((skipBuffer == null) || (skipBuffer.length < nn)) //数组不为空 || 数组长度小于跳过的字符数
skipBuffer = new char[nn];
long r = n;
while (r > 0) {
int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
if (nc == -1)
break;
r -= nc;
}
return n - r;
}
} //表示此流是否已准备好读取。
public boolean ready() throws IOException {
return false;
} /表示该流是否支持mark()操作
public boolean markSupported() {
return false;
} //标记当前流中的位置。
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark() not supported");
} //重置
public void reset() throws IOException {
throw new IOException("reset() not supported");
} //关闭流并释放与之关联的任何系统资源。
abstract public void close() throws IOException; }

三、Writer(输出)

public abstract class Writer implements Appendable, Closeable, Flushable {

    //用于保存字符串和单个字符的写的临时缓冲区
private char[] writeBuffer; //缓存区大小
private static final int WRITE_BUFFER_SIZE = 1024; protected Object lock; protected Writer() {
this.lock = this;
} protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
} //写入一个字符
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
} //写入字符数组。
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
} //写入字符数组的一部分。
abstract public void write(char cbuf[], int off, int len) throws IOException; //写一个字符串。
public void write(String str) throws IOException {
write(str, 0, str.length());
} //写入字符串的一部分
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= WRITE_BUFFER_SIZE) { //长度小于最大缓存长度
if (writeBuffer == null) {
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
cbuf = writeBuffer;
} else { //如果长度大于缓存区的长度,重新新建一个len长度的字符数组。但是不要永久地分配非常大的缓冲区。
cbuf = new char[len];
}
str.getChars(off, (off + len), cbuf, 0);//获取str字符串 从off开始,长度为len的字符串
write(cbuf, 0, len);
}
} //将指定的字符序列追加到写入器。
public Writer append(CharSequence csq) throws IOException {
if (csq == null)
write("null");
else
write(csq.toString());
return this;
} //向写入器追加指定字符序列的子序列。
public Writer append(CharSequence csq, int start, int end) throws IOException {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
} //将指定的字符附加到写入器。
public Writer append(char c) throws IOException {
write(c);
return this;
} //刷新流
abstract public void flush() throws IOException; //关闭流
abstract public void close() throws IOException; }

JavaIO -- Reader 和 Writer的更多相关文章

  1. java IO之字节流和字符流-Reader和Writer以及实现文件复制拷贝

    接上一篇的字节流,以下主要介绍字符流.字符流和字节流的差别以及文件复制拷贝.在程序中一个字符等于两个字节.而一个汉字占俩个字节(一般有限面试会问:一个char是否能存下一个汉字,答案当然是能了,一个c ...

  2. Java之IO(十)Reader和Writer

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7071733.html 1.前言 之前的章节已经将Java8的io包中的字节流介绍完毕了.本章开始介绍Java的I ...

  3. java-I/O File类(5)-Reader和Writer、OutputStreamWriter 、BufferedWriter、字节流和字符流的区别

      标签: outputstreamwriterreader字符file方法 2015-05-14 23:06 469人阅读 评论(0) 收藏 举报  分类: 孙鑫-java基础(16)  I-O(4 ...

  4. 牛客网Java刷题知识点之输入流、输出流、字节流、字符流、字节流的抽象基类(InputStream、OutputStream)、字符流的抽象基类(Reader、Writer)、FileWriter、FileReader

    不多说,直接上干货! IO流用来处理设备之间的数据传输. java对数据的操作是通过流的方式. java用于操作流的对象都在IO包中. IO流按操作数据分为两种:字节流和字符流. IO流按流向分为:输 ...

  5. Java中的流(3)字符流-Reader和Writer

    java中提供了处理以16位的Unicode码表示的字符流的类,即以Reader和Writer 为基类派生出的一系列类.  1.Reader和Writer  这两个类是抽象类,只是提供了一系列用于字符 ...

  6. Java I/O(三)各种Reader和Writer读写器、RandomAccessFile随机访问文件、序列化

    2019 01/01 八.Reader和Writer读写器 前面讲的输入输出流的基本单位都是字节,因此可以称为“字节流”,读写器是以字符为基本单位,可以称为“字符流”.它们的使用方法非常相似,因此我考 ...

  7. Java IO: Reader和Writer

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) Reader 原文链接 Reader是Java IO中所有Reader的基类.Reader与Input ...

  8. Java IO: Reader And Writer

    原文链接 作者: Jakob Jenkov  译者: 李璟(jlee381344197@gmail.com) Java IO的Reader和Writer除了基于字符之外,其他方面都与InputStre ...

  9. Reader和Writer区别final.finally.finalize区别

    Reader和Writer是字符操作流,Writer是输出的,而Reader是输入的. 首先找到一个文件,比如:File file=new File("."+File.separa ...

随机推荐

  1. 数据结构实验之查找三:树的种类统计(SDUT 3375)

    C: #include <stdio.h> #include <stdlib.h> #include <string.h> struct node { char d ...

  2. 【原创】go语言学习(十四)IO操作1

    目录: 格式化输入 格式化输出 终端输入输出背后的原理理 bufio包的使用 命令行参数处理理和urfave/cli使用 格式化输入 1.从终端获取⽤用户的输入 格式化输入 fmt.Scan(a …i ...

  3. 接口测试命令Httpie的使用

    相比于curl命令,Httpie提供更清晰友好的界面,并支持授权,代理等操作 主要特性 直观的语法 格式化和色彩化的终端输出 内置 JSON 支持 支持上传表单和文件 HTTPS.代理和认证 任意请求 ...

  4. C# 图片进行马赛克处理

    MosaicHelper.AdjustTobMosaic( @"C:\Users\xxxue\Desktop\QQ图片20180704142029.jpg", @"C:\ ...

  5. Synchronized 原理

    1.同步代码块: 反编译结果: monitorenter : 每个对象有一个监视器锁(monitor).当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取moni ...

  6. dp之斜率优化

    前几天想练练思维,所以从cf上随便找了一道dp题,看完题意后第一感觉很简单,就是简单的区间dp题,但是看到数据范围的我顿时就懵了,(1≤n≤105) emmmmmmmm,按照普通的思路肯定会超时的.. ...

  7. PL/SQL配置和连接远端数据库

    1. 安装与配置 (1) 安装 因为是免安装的绿色版,所以解压到目录就可以了,保证目录中没有空格.下划线和中文字符. 还有一点,PL/SQL需要和Oracle的版本一致,都是32位或者都是64位,否则 ...

  8. Leetcode题 257. Binary Tree Paths

    Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...

  9. 微信小程序设置滚动条

    前言 又很久没有写东西了,上周开始将一个APP和一个网站的内容整合到微信小程序中,到这会儿终于搞得快结束了,才发现为啥我的小程序滚动视图没有滚动条,这是闹哪样,没有滚动条的滚动是没有灵魂的. 客官可移 ...

  10. Java 签名(SHA1WithRSA、SHA256WithRSA、SHA256withECDSA)

    RSA1.RSA256 签名 public static String MakeSign(String Data) { try { byte[] data = Data.getBytes(); byt ...