Java IO - Reader&Writer
来源:互联网 发布:sql update 数据 编辑:程序博客网 时间:2024/04/29 18:10
基本概念
Reader/Writer(字符读取流/字符写入流),是所有字符操作流的父类。
同字节流不同,它们本身是抽象类。
继承关系如下:
源码分析
1.Reader
类结构图
成员变量
/* * 用来在流上同步操作的对象。 * 为了提高效率,字符流对象可以使用其自身以外的对象来保护关键部分。 * 因此,子类应使用此字段中的对象,而不是 this 或者同步的方法。 */protected Object lock;// 表示跳跃(丢弃)操作时能丢弃的最大字符数量private static final int maxSkipBufferSize = 8192;// 跳跃缓冲数组,用来保存跳跃操作时读取的字符内容private char skipBuffer[] = null;
构造函数
protected Reader() { // 将字符流对象赋于 lock,说明我们操作的不是字符流本身,而是 lock this.lock = this;}protected Reader(Object lock) { if (lock == null) { throw new NullPointerException(); } this.lock = lock;}
read 方法,这里定义了 4 种读取方式。
①② 依靠 ③ 实现。
③ 为抽象方法,留给子类实现。
④ 是字节输入流所没有的读取方式。
//① 读取单个字符public int read() throws IOException { char cb[] = new char[1]; //关键-->创建了只有1个字符容量的数组,然后将字符读入该字符数组。 if (read(cb, 0, 1) == -1) { //到达 I/O 流末尾返回 -1 return -1; } else { //否则返回整数字符,范围为 0 到 65535 之间 (0x00-0xffff), return cb[0]; }}//② 将字符读入数组,返回读取的字符数public int read(char cbuf[]) throws IOException { return read(cbuf, 0, cbuf.length);}//③ 将字符读入数组的某一部分。抽象方法,留给子类实现public abstract int read(char cbuf[], int off, int len) throws IOException;//④ 将字符读入指定的字符缓冲区,返回读取的字符数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; }
skip,跳跃操作。具体原理在 InputStream 中已介绍过了,这里不在细说。
与 InputStream 的 skip 方法不同,字符输入流的 skip 方法是同步操作,是线程安全的。
public long skip(long n) throws IOException { if (n < 0L) { throw new IllegalArgumentException("skip value is negative"); } //nn 表示将要创建的缓冲数组的容量大小 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; }}
剩余方法
// 如果确保流的下一次读取不堵塞,则返回 true,否则返回 false,但并不表示下一次读取会堵塞public boolean ready() throws IOException { return false;}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;
2.Writer
类结构图
成员变量
//缓冲数组,默认写入的内容会暂时保存在该字符数组里private char[] writeBuffer;//缓冲数组的大小,不可变private final int writeBufferSize = 1024;//同 Readerprotected Object lock;
构造函数
protected Writer() { this.lock = this;}protected Writer(Object lock) { if (lock == null) { throw new NullPointerException(); } this.lock = lock;}
wirter 方法,这里定义 5 种写入方式
①② 依靠 ③ 实现。
③ 为抽象方法,留给子类实现。
④⑤ 是字节输出流所没有的读取方式。
// ①写入单个字符public void write(int c) throws IOException { synchronized (lock) { if (writeBuffer == null) { writeBuffer = new char[writeBufferSize]; } //将字符的 int 写入缓冲数组 writeBuffer[0] = (char) c; write(writeBuffer, 0, 1); }}// ②写入字符数组public void write(char cbuf[]) throws IOException { write(cbuf, 0, cbuf.length);}// ③写入字符数组的某一部分,抽象方法public bstract 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 <= writeBufferSize) { if (writeBuffer == null) { writeBuffer = new char[writeBufferSize]; } cbuf = writeBuffer; } else { cbuf = new char[len]; } //String 的方法,将字符串复制到字符数组 str.getChars(off, (off + len), cbuf, 0); write(cbuf, 0, len); }}
append 方法,这里定义了 3 种添加方式。
具体实现通过调用相应的 write 方法完成,并返回 Writer 对象
// 将指定字符添加到此 writer,并返回此 writerpublic Writer append(char c) throws IOException { write(c); return this;}// 将指定字符序列添加到此 writer,并返回此 writerpublic Writer append(CharSequence csq) throws IOException { if (csq == null){ //字符序列为空,则添加 null 这4个字符到 writer write("null"); }else{ write(csq.toString()); } return this;}// 将指定字符序列的子序列添加到此 writer,并返回此 writerpublic 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 abstract void flush() throws IOException;public abstract void close() throws IOException;
0 0
- java IO Reader Writer
- Java IO - Reader&Writer
- java io (四) Reader Writer
- Java IO reader and writer
- Java IO之Reader/Writer
- Java IO 字符流 Reader和Writer
- java-io初步:Reader、Writer、Buf…
- Java - IO - 字符流 - Writer - Reader
- java Io reader writer 笔记3
- Java IO(十二):Reader 和 Writer
- java IO笔记(Reader/Writer)
- 4 Java IO:Reader 和 Writer
- IO之Reader Writer
- IO file reader /writer
- 24. Java IO: Reader-Writer && Java IO: PrintWriter
- JAVA IO系列----FileInputStream和FileOutputStream类,Reader和Writer
- 黑马程序员--------java IO流 Reader、Writer、InputStream、OutputStream
- Java-IO之字符输入输出流(Reader和Writer)
- [dfs序+线段树] codeforces 343D. Water Tree
- vertica-ksafe
- 用viewpager实现网络图片的加载并滑动
- Docker 建私有库
- 2016.5.25(2)
- Java IO - Reader&Writer
- bash 起别名
- MySQL远程root登录
- 第12周项目3:数组类运算的实现
- Dockerfile、Docker镜像和Docker容器的关系
- RecyclerView 简单实现拖拽和滑动
- reahat Linux下bind的安装及配置
- 秒级处理海量数据,浙江移动大数据平台是怎么做到的
- 绘制优化