一、简介

  设计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. UOJ#467. 【ZJOI2019】线段树 线段树,概率期望

    原文链接www.cnblogs.com/zhouzhendong/p/ZJOI2019Day1T2.html 前言 在LOJ交了一下我的代码,发现它比选手机快将近 4 倍. 题解 对于线段树上每一个节 ...

  2. [bzoj 3534][Sdoi2014] 重建

    传送门 Description  T国有N个城市,用若干双向道路连接.一对城市之间至多存在一条道路. 在一次洪水之后,一些道路受损无法通行.虽然已经有人开始调查道路的损毁情况,但直到现在几乎没有消息传 ...

  3. 跑shell脚本出错问题以及解决。

    脚本信息: #!/bin/bash function hello(){ cat <<YJT echo "hello world!!!" YJT } hello 错误: ...

  4. vue点击父组件里面的列表动态传值到子组件

    <template> <div> 爸爸 <div style="background-color:yellow;margin-top:10px" v- ...

  5. Go 与 JSON

    Go 中通过标准库encoding/json.encoding.xml.encoding/asn1和其他库对 JSON.XML.ASN.1 和其他类型的标准的编码和解码提供了良好的支持,这里对使用最多 ...

  6. 项目管理工具-OmniPlan 3 for Mac

    链接:https://pan.baidu.com/s/1tp_37fHXHwJuklL1nNSwig  密码:l0sf 激活迷药(里面自带的keygen不能用,用这个好使): Name: Appked ...

  7. ES--Kibana相关操作创建索引和Mapping

    创建索引 kibana 使用如下命令进行创建索引内容. PUT test_index/ 创建别名 POST _aliases { "actions": [{ "add&q ...

  8. 贝济埃曲线quadTo与传统的手势轨迹平滑度对比分析

    package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.Canvas ...

  9. 自定义控件的属性declare-styleable

    在res/values文件下定义一个attrs.xml文件,代码如下: <?xml version="1.0" encoding="utf-8"?> ...

  10. Redis Sentinel 高可用服务架构搭建

    https://www.cnblogs.com/xishuai/p/redis-sentinel.html