Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13
转载自 Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13
一:CharArrayReader
1、类功能简介:
字符数组输入流car 、与ByteArrayInputStream相同、用于将自带的内置缓存字符数组中的字符读取到程序中。与ByteArrayInputStream不同的是:当调用car的close方法是将内置缓存数组cbuffer设为null、而且car会抛出IOException异常(ensureOpen方法、即当cbuffer为null时则认为car关闭)。方法与使用功能与bais很相似、说白了区别就在于一个是从内置字节数组中读取字节、一个是从内置字符数组中读取字符。有一点是与bais不同的地方、就是他们的父类的区别、Reader比InputStream多实现一个Readable接口、这个接口要求提供一个方法、是将字符数组读取到指定的缓存数组中、其实完全可以用read(char[] cbuf, int off, int len)来代替实现。。。
2、CharArrayReader API简介:
A:关键字
protected char buf[]; 自带字符数组
protected int pos; buf中下一个要被读取的字符位置
protected int markedPos = 0; buf中被mark的字符下标
protected int count; 字符数组中总数、buf中索引为count和下一个都没有字符存在。
B:构造方法
CharArrayReader(char buf[]); 使用传入的buf构造CharArrayReader
CharArrayReader(char buf[], int offset, int length); 使用传入的buf的一部分构造CharArrayReader
C:一般方法
void close(); 关闭此流、
void mark(int readAheadLimit); 标记当前流读取的位置
void markSupport(); 检测此流是否支持标记
int read(); 读取一个字符、并以整数形式返回
int read(char[] c, int off, int len); 将buf中len个字符读取到下标从off开始的b中、返回读取的字符个数
boolean ready(); 查看CharArrayReader是否可读。
void reset(); 将此流开始位置重置到最后一次调用mark是流的读取位置
long skip(long n); 丢弃buf中n个字符、返回实际丢弃的字符个数
3、源码分析
package com.chy.io.original.code; import java.io.IOException; /** * 字符数组输入流 */
public class CharArrayReader extends Reader { /** 自带字符数组 */ protected char buf[]; /** buf中下一个要被读取的字符位置 */ protected int pos; /** buf中被mark的字符下标 */ protected int markedPos = 0; /** * 字符数组中总数、buf中索引为count和下一个都没有字符存在。 */ protected int count; /** * 使用传入的buf构造CharArrayReader、并初始化CharArrayReader的buf、以及buf中将要被读取的字符的下标及总数。 */ public CharArrayReader(char buf[]) { this.buf = buf; this.pos = 0; this.count = buf.length; } /** * 使用传入的buf构造CharArrayReader、并初始化CharArrayReader的buf、以及buf中将要被读取的字符的下标及总数。 */ public CharArrayReader(char buf[], int offset, int length) { if ((offset < 0) || (offset > buf.length) || (length < 0) || ((offset + length) < 0)) { throw new IllegalArgumentException(); } this.buf = buf; this.pos = offset; this.count = Math.min(offset + length, buf.length); this.markedPos = offset; } /** 检测此流是否关闭、看此流的close()方法就能明白这个方法*/ private void ensureOpen() throws IOException { if (buf == null) throw new IOException("Stream closed"); } /** * 读取单个字符 */ public int read() throws IOException { synchronized (lock) { ensureOpen(); if (pos >= count) return -1; else return buf[pos++]; } } /** * 将buf中len个字符读取到下标从off开始的b中、返回读取的字符个数。 */ public int read(char b[], int off, int len) throws IOException { synchronized (lock) { ensureOpen(); if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } //buf中没有字符 if (pos >= count) { return -1; } //buf中字符不够len个 if (pos + len > count) { len = count - pos; } //传入的len<=0、返回0 if (len <= 0) { return 0; } System.arraycopy(buf, pos, b, off, len); pos += len; return len; } } /** * 丢弃buf中n个字符、返回实际丢弃的字符个数。 */ public long skip(long n) throws IOException { synchronized (lock) { ensureOpen(); //如果buf中剩余字符不够n个、丢弃buf中现有所有字符 if (pos + n > count) { n = count - pos; } //传入的n为负、不丢弃。 if (n < 0) { return 0; } pos += n; return n; } } /** * 查看CharArrayReader是否可读。判断条件是buf中是否还有字符存在。 */ public boolean ready() throws IOException { synchronized (lock) { ensureOpen(); return (count - pos) > 0; } } /** * 是否支持mark?是 */ public boolean markSupported() { return true; } /** * 标记当前buf中下一个将要被读取的字符下标。 * 传入的readAheadLimit同ByteArrayInputStream一样、无效。 */ public void mark(int readAheadLimit) throws IOException { synchronized (lock) { ensureOpen(); markedPos = pos; } } /** * 将此流开始位置重置到最后一次调用mark是流的读取位置。 */ public void reset() throws IOException { synchronized (lock) { ensureOpen(); pos = markedPos; } } /** * 关闭、清空buf。 */ public void close() { buf = null; }
}
4、实例演示:
二:CharArrayWriter
1、类功能简介:
字符数组输出流caw、用于将字符写入到内置字符缓存数组char[] buf中、当此数组存放满员时会自动扩容、同样与ByteArrayOutputStream相比他也提供了几个操作buf中字符的方法、可使用 toCharArray() 和 toString() 获取数据、还可使用writeTo(Writer out)将buf写入到底层流中。同样在此类上调用 close()、flush()无效,不会产生IOException、并且在关闭该流后仍然可以调用此类中的各个方法。
2、CharArrayWriter API简介:
A:关键字
protected char buf[]; 用于存放写入CharArrayWriter的字符、存满自动扩容。
protected int count; buf中现有的字符数
B:构造方法
public CharArrayWriter() 使用默认buf大小创建CharArrayWriter。
public CharArrayWriter(int initialSize) 使用指定的buf大小创建CharArrayWriter。
C:一般方法
CharArrayWriter append(CharSequence csq) 将一串有序字符序列写入buf中 CharArrayWriter append(CharSequence csq, int start, int end) 将一串有序字符序列的一部分写入buf中 CharArrayWriter append(char c) 将一个字符写入buf中 void close() 关闭此流(没有效果) void flush() flush此流(没有效果) void reset() 清空buf、重头开始 int size() 查看当前buf中字符总数 char[] toCharArray() 将buf中内容转换成char[] String toString() 将buf中字符转换成String返回 void write(int c) 写入一个字符。 void write(char c[], int off, int len) 将一个char[]的一部分写入buf中、若buf满、扩容。 void write(String str, int off, int len) 将一个字符串写入buf中、满自动扩容 void writeTo(Writer out) 将buf中现有的字节写入到subWriter(out)中
3、源码分析
package com.chy.io.original.code; import java.io.IOException;
import java.util.Arrays; /** * Writer的一个子类、可将字符写入到自带的一个缓存字符数组buf中、 * 当buf写满时、会自动扩容。 */
public class CharArrayWriter extends Writer { /** * 用于存放写入CharArrayWriter的字符、存满自动扩容。 */ protected char buf[]; /** * buf中现有的字符数 */ protected int count; /** * 使用默认buf大小创建CharArrayWriter。 */ public CharArrayWriter() { this(32); } /** * 使用指定的buf大小创建CharArrayWriter。 */ public CharArrayWriter(int initialSize) { if (initialSize < 0) { throw new IllegalArgumentException("Negative initial size: " + initialSize); } buf = new char[initialSize]; } /** * 写入一个字符。 */ public void write(int c) { synchronized (lock) { int newcount = count + 1; //如果buf存满、则将buf容量扩大1倍、并将原来buf中count字符copy到新的buf中 if (newcount > buf.length) { buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } //将新写入的字符存入到buf第count个下标位置。 buf[count] = (char)c; count = newcount; } } /** * 将一个char[]的一部分写入buf中、若buf满、扩容。 */ public void write(char c[], int off, int len) { if ((off < 0) || (off > c.length) || (len < 0) || ((off + len) > c.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } synchronized (lock) { int newcount = count + len; if (newcount > buf.length) { buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } System.arraycopy(c, off, buf, count, len); count = newcount; } } /** * 将一个字符串写入buf中、满自动扩容 */ public void write(String str, int off, int len) { synchronized (lock) { int newcount = count + len; if (newcount > buf.length) { buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } str.getChars(off, off + len, buf, count); count = newcount; } } /** * 将buf中现有的字节写入到subWriter(out)中 */ public void writeTo(Writer out) throws IOException { synchronized (lock) { out.write(buf, 0, count); } } /** * 将一串有序字符序列写入buf中 */ public CharArrayWriter append(CharSequence csq) { String s = (csq == null ? "null" : csq.toString()); write(s, 0, s.length()); return this; } /** * 将一串有序字符序列的一部分写入buf中 */ public CharArrayWriter append(CharSequence csq, int start, int end) { String s = (csq == null ? "null" : csq).subSequence(start, end).toString(); write(s, 0, s.length()); return this; } /** * 将一个字符写入buf中 */ public CharArrayWriter append(char c) { write(c); return this; } /** * 清空buf、重头开始 */ public void reset() { count = 0; } /** * 将buf中内容转换成char[] */ public char toCharArray()[] { synchronized (lock) { return Arrays.copyOf(buf, count); } } /** * 查看当前buf中字符总数 */ public int size() { return count; } /** * 将buf中字符转换成String返回 */ public String toString() { synchronized (lock) { return new String(buf, 0, count); } } /** * flush CharArrayWriter、因此方法对CharArrayWriter没有效果、所以方法体是空! */ public void flush() { } /** * 同样、关闭CharArrayWriter没有用、调用close()关闭此流、此流的方法一样能用。 */ public void close() { } }
4、实例演示:
package com.chy.io.original.test; import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
/** * * @author andyChen * @version 1.1 , 13/11/15 * */
public class CharArrayTest { private static final String str = "abcdefghijklmnopqrstuvwxyz"; private static char[] charArray = new char[26]; static{ for(int i=0; i<str.length(); i++){ charArray[i] = str.charAt(i); } } private static void testCharArrayReader() throws IOException{ CharArrayReader car = new CharArrayReader(charArray); if(!car.ready()){ return; } /** * 与ByteArrayInputStream差不多、区别就是一个字节一个字符。 * 不爽的地方在于CharArrayReader没有提供 car.available()方法、不能随时知道buf中还有多少可以读取的字符. */ //将写入CharArrayReader内置字符缓存数组buf中的第一个字符输出、并且标记buf下一个可读字符索引的pos++ System.out.println((char)car.read()); //读取CharArrayReader中buf字符、返回实际读取的字符数。 char[] buf = new char[5]; car.read(buf, 0, 5); printChar(buf); //标记当前CharArrayReader流的位置、当下次调用reset后继续使用CharArrayReader读取时从此标记的位置开始读取。 //即用 markedPos记录当前的pos car.mark(0); //丢弃从buf下一个将要读取的字符开始的10个字符、返回实际丢弃的字符。 car.skip(10); //读取10个字符 char[] buf2 = new char[10]; car.read(buf2, 0, 10); printChar(buf2); //查看buf中是否还有有效可供读取的字符 System.out.println(car.ready()); //重置mark标记的位置、即将markedPos的值重新赋给pos、这样当读取下一个字符时就是读取buf的索引为pos的字符。 car.reset(); System.out.println((char)car.read()); } private static void testCharArrayWriter() throws IOException{ File file = new File("D:\\caw.txt"); CharArrayWriter caw = new CharArrayWriter(); //将第一个 a-z 字符写入caw内置buf中 for(int i=0; i<charArray.length; i++){ caw.write(charArray[i]); } caw.write("\r\n"); //将第二个a-z字符写入caw内置buf中 caw.write(charArray, 0, charArray.length); caw.write("\r\n"); //将第三个a-z字符写入buf中 caw.write(charArray); caw.write("\r\n"); //将第四个a-z字符写入buf中 caw.write(new String(charArray), 0, charArray.length); caw.write("\r\n"); //将第五个a-z字符写入buf中 for(int i=0; i<charArray.length; i++){ caw.append(charArray[i]); } caw.append("\r\n"); //此方法传入的是一个CharSequence、CharArray是一个CharSequence的一个子类、但是为什么不行? //caw.append(charArray); //caw.append("\r\n"); //将第六个a-z字符写入buf中 caw.append(new StringBuffer(new String(charArray))); caw.append("\r\n"); /** * 简单说明:caw.append()传入的参数时CharSequence、char * 但是上面传入的String、StringBuffer、StringBuilder也行、很简单、他们是CharSequence接口的实现类。 */ String aboveResult = caw.toString(); char[] buf = caw.toCharArray(); System.out.println("String aboveResult: "+ "\r\n" + aboveResult); System.out.println("====================================="); System.out.println("char[] result : " + "\r\n" +new String(buf)); FileWriter fw = new FileWriter(file); caw.writeTo(fw); fw.flush(); fw.close(); } /** * 将写入文件的中文读取出来 * 这里没有什么组织性、 * 自己可以尝试不同组合的读取、加深理解。 */ private static void test() throws FileNotFoundException, IOException { File file = new File("D:\\bos.txt"); FileOutputStream fos = new FileOutputStream(file); FileInputStream fis = new FileInputStream(file); fos.write("陈华应".getBytes()); fos.flush(); fos.close(); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); char[] cbuf = new char[fis.available()]; br.read(cbuf); CharArrayReader car = new CharArrayReader(cbuf); char[] newCbuf = new char[fis.available()]; car.read(newCbuf); System.out.println(new String (newCbuf)); } private static void printChar(char[] buf){ for(char c : buf ){ System.out.print(c); } System.out.println(); } public static void main(String[] args) throws Exception{ testCharArrayWriter(); testCharArrayReader(); test(); }
}
总结:
本质是将字符写入内置字符缓存数组中、或者是将字符从内置缓存数组读取到程序中(内置字符缓存数组中字符的来源是在构造CharArrayReader时传入的字符数组)。
Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13相关推荐
- Java_io体系之BufferedWriter、BufferedReader简介、走进源码及示例——16
Java_io体系之BufferedWriter.BufferedReader简介.走进源码及示例--16 一:BufferedWriter 1.类功能简介: BufferedWriter.缓存字符输 ...
- Java_io体系之RandomAccessFile简介、走进源码及示例——20
Java_io体系之RandomAccessFile简介.走进源码及示例--20 RandomAccessFile 1. 类功能简介: 文件随机访问流.关心几个特点: 1.他实现的接口不再 ...
- Java_io体系之PipedInputStream、PipedOutputStream简介、走进源码及示例——06
Java_io体系之PipedInputStream/PipedOutputStream简介.走进源码及示例--06 --管道输出流.必须建立在管道输入流之上.所以先介绍管道输出流.可以先看源码或者总 ...
- Java_io体系之PipedWriter、PipedReader简介、走进源码及示例——14
Java_io体系之PipedWriter.PipedReader简介.走进源码及示例--14 --管道字符输出流.必须建立在管道输入流之上.所以先介绍管道字符输出流.可以先看示例或者总结.总结写的有 ...
- linux内核体系学习路径_Linux内核分析(一)linux体系简介|内核源码简介|内核配置编译安装...
从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底,同时在博文中如果那些地方有问题还请各位大神为我讲解. 今天我们会分析到以下内容: 1. Linux体系结构简介 ...
- ThreadLocal 简介 案例 源码分析 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Java生鲜电商平台-电商会员体系系统的架构设计与源码解析
Java生鲜电商平台-电商会员体系系统的架构设计与源码解析 说明:Java生鲜电商平台中会员体系作为电商平台的基础设施,重要性不容忽视.我去年整理过生鲜电商中的会员系统,但是比较粗,现在做一个最好的整 ...
- 编译器 llvm clang 源码转换示例
编译器 llvm clang 源码转换示例 从git获取llvm项目的源码方式: git clone https://github.com/llvm/llvm-project.git 下载源码后,进入 ...
- H5音乐播放器(包含源码与示例)
H5音乐播放器(包含源码与示例) 基于Angular+ionic的H5音乐播放器,源码:https://gitee.com/CrimsonHu/h5-music-player 示例地址 建议使用原版c ...
最新文章
- 7 款可替代 top 命令的工具!(二)
- Java 中商业运算必备的精确运算类:BigDecimal
- 如何用python画爱心型线_python怎么画爱心
- 1 python基础
- Spring Boot中使用@JsonComponent
- 自动化部署kvm虚拟机_自动化虚拟助手
- 乐高无限无法连接到服务器,乐高无限近期热点问题FQ 新手问题解答
- 关于CentOS7虚拟机出现Failed to start LSB: Bring up/down的解决方法
- PostgreSql 分页limit
- Eclipse优化设置技巧
- 操作必须使用一个可更新的查询
- 汇客huikeCRM项目实战-牛刀小试
- 前端取值的方式(ModelMap)
- mac如何打开php文件夹,苹果Mac系统怎么打开隐藏文件夹Library?_苹果MA
- 9.9 买礼物的艰辛 2719
- Windows共享Linux打印机,在Ubuntu系统中使用局域网内Windows共享打印机的方法
- 如何使用windows的计划任务?计划任务
- 为什么鸿蒙系统有摩尔纹,摩尔纹
- WARN [Consumer clientId=consumer-console-consumer-22243-1, groupId=console-consumer-22243] Bootstrap
- 产业互联网周报:钉钉被曝组织优化,涉及自研 SaaS、硬件部门;马斯克暂停Twitter收购;谷歌发布AlloyDB数据库服务...
热门文章
- learnpython3thehardway视频_LearnPython3theHardWay__Excercise 13 Parameters, Unpacking, Variables
- mysql 5.5 免安装_mysql 5.5.56免安装版配置方法
- 多重背包问题以及二进制优化
- Piggy-Bank POJ - 1384(完全背包+背包放满)
- 计算机连接拒绝访问,Win10系统下Windows无法连接到打印机,拒绝访问的解决办法...
- word List 11
- 数据结构----冒泡排序
- char *与char []
- Codeforces Round #588 (Div. 2) F. Konrad and Company Evaluation 图论 + 建反图 好题
- Rinne Loves Xor