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、实例演示:

参见下面的实例演示、一般喜欢将两者放在一个测试类中、分成两个方法testCharArrayReader()、testCharArrayWriter()、有关联的两个类还会多出关联测试、这样有条理点。

二: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时传入的字符数组)。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hibernate中使用Criteria查询及注解——(Emp.hbm.xml)

Emp.hbm.xml 员工信息表的映射文件 <?xml version"1.0" encoding"utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&…

Connect 2016过后,你的信仰势必需要更大的容器

嗯……在为大家回顾昨夜里的 Connect 2016 大会之前&#xff0c;容M姐向大家致歉&#xff0c;昨天的B站首秀因为卡顿未能如约和大家一起互动弹幕&#xff0c;准备的奖品都没有发出去啊&#xff01;&#xff01;这个大家表生气&#xff0c;稍后M姐依旧会发给大家的呢&#xff01…

mysql数据横表变成竖表_MySQL中横表和竖表相互转换

一 竖表转横表1. 首先创建竖表create table student (id varchar(32) primary key,name varchar (50) not null,subject varchar(50) not null,result int);2. 插入数据insert into student (id, name, subject, result) values (0001, 小明, 语文, 83);insert into student …

Java压缩技术(二) ZIP压缩——Java原生实现

转载自 Java压缩技术&#xff08;二&#xff09; ZIP压缩——Java原生实现 查过相关资料后才知道&#xff0c;ZIP应该算作归档类的压缩算法&#xff0c;每一门学科都可深可浅&#xff01; 闲言少叙&#xff0c;先说ZIP压缩。 zip压缩需要通过ZipOutputStream 执行write方法将…

总结尚硅谷的视频springboot视频

这16个章节也就讲个大概&#xff0c;更多内容需要你自己去学习。 第1章尚硅谷SpringBoot入门 P01、尚硅谷_SpringBoot_入门-课程简介 P02、尚硅谷_SpringBoot_入门-Spring Boot简介 P03、尚硅谷_SpringBoot_入门-微服务简介 P04、尚硅谷_SpringBoot_入门-环境准备 P05、尚硅谷_…

微软加入Linux基金会共建开源生态,并对谷歌加入.NET社区的举措表示欢迎

纽约 — 2016年11月16日 — 在周三的年度性Connect();开发者大会上&#xff0c;微软公司公布了一系列产品与合作&#xff0c;以此为基础帮助开发者打造智能的跨平台应用和服务&#xff0c;进而强化微软在Azure云平台方面的优势。微软全球执行副总裁兼云计算与企业事业部负责人 …

mybatis配置mysql连接数_springBoot配置mybatis链接数据库

springBoot配置mybatis链接数据库添加pom包,修改 pom.xml 文件org.mybatis.generatormybatis-generator-core1.3.5org.mybatis.spring.bootmybatis-spring-boot-starter1.3.2mysqlmysql-connector-java修改配置文件application.yml#启动端口server:port: 8001spring:#配置数据源…

Java压缩技术(三) ZIP解压缩——Java原生实现

转载自 Java压缩技术&#xff08;三&#xff09; ZIP解压缩——Java原生实现 解压缩与压缩运作方式相反&#xff0c;原理大抵相同&#xff0c;由ZipInputStream通过read方法对数据解压&#xff0c;同时需要通过CheckedInputStream设置冗余校验码&#xff0c;如&#xff1a; J…

19年8月 字母哥 第二章 RESTFul接口实现与测试 看到这里了

第二章 RESTFul接口实现与测试 2.1.RESTFul接口与http协议状态表述 2.2.常用注解开发一个RESTFul接口 2.2看完了 2.3 JSON数据处理与PostMan测试 树哪里是可以加上去的 list<treeNode> listTreeNode; 为空就不显示了 20%是常用的 80%是不常用的 我只是讲解了20…

java实现验证码3秒刷新一次

<?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://xmlns.jcp.org/xml/ns/javaeehttp://x…

Hibernate中使用Criteria查询及注解——(Dept.hbm.xml)

Dept.hbm.xml 部门表的映射文件: <?xml version"1.0" encoding"utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&qu…

CentOS上安装SQL Server vNext CTP1

今天微软正式发布上SQL Server 2016 SP1,根据以往的SP1定律&#xff0c;可以在生产环境上使用了。打了SP1的标准版将具有企业版几乎所有的的功能。只有RAM 超过128GB或者超过24核心或者超过4路的环境才必须要安装企业版。 还有一个重要的发布&#xff1a;SQL Server vNext on L…

python弹出窗口 闪烁_Python。得到闪烁/闪烁的窗口

首先&#xff0c;大多数程序通过调用^{}(或包装它的高级函数)来刷新窗口。但是&#xff0c;有一些应用程序主要来自微软&#xff0c;他们做一些定制的东西&#xff0c;在终端用户看来就像是在闪窗&#xff0c;但在封面下看起来可能不一样。希望你不在乎任何这样的定制应用。在无…

Java压缩技术(七) TAR——Commons实现

转载自 Java压缩技术&#xff08;七&#xff09; TAR——Commons实现 顺便复习一遍linux命令&#xff1a; tar cf <file.tar> <file>将由文件<file>创建名为<file.tar>归档文件&#xff0c;同时保留原文件。 tar xf <file.tar>将由归档文件<…

[干货来袭]MSSQL Server on Linux预览版安装教程(先帮大家踩坑)

前言 昨天晚上微软爸爸开了全国开发者大会,会上的内容,我就不多说了,园子里面很多.. 我们唐总裁在今年曾今透漏过SQL Server love Linux,果不其然,这次开发者大会上就推出了MSSQL Server on Linux预览版 官方地址:https://docs.microsoft.com/zh-cn/sql/linux/ E文好的可以自己…

MVC三层架构理解

MVC三层架构 什么是MVC&#xff1a; Model view Controller 模型、视图、控制器 以前的架构 用户直接访问控制层&#xff0c;控制层就可以直接操作数据库&#xff1b; servlet--CRUD-->数据库 弊端&#xff1a;程序十分臃肿&#xff0c;不利于维护 servlet的代码中&…

spring boot建立项目 git推送giteee

gitee上创建项目时候不要创建readme.md 创建完全空的项目 不然上次会报错的 $ git init 初始化git $ git status $ git add . $ git status $ git commit -am 初次建立项目 $ git remote add origin https://gitee.com/yjb1091947832/yangjiabin.git…

vba mysql update多字段_vba操作Mysql使用UPDATE一次更新多组数据

网上查到综合后确定的update语法范例&#xff1a;UPDATE mytable SET myfield CASE WHEN 1 THEN ‘value‘ WHEN 2 THEN ‘value‘ WHEN 3 THEN ‘value‘ END WHERE id IN (1,2,3)下面是我写的一个通用的update库表内容过程&#xff1a;kku为库表&#xff0c;zd为字段&#x…

Hibernate中使用Criteria查询及注解——(hibernate.cfg.xml)

hibernate.cfg.xml hibernate主配置文件&#xff1a; <?xml version1.0 encodingUTF-8?> <!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration…

为什么我不选阿里云(一)

我是资深阿里黑&#xff0c;“资深”体现在我黑阿里和阿里云从来有理有据&#xff0c;我不是小白用户&#xff0c;我本身就是云架构师&#xff0c;我目前主要推荐中国客户上Azure和AWS。 阿里巴巴&#xff08;BABA&#xff09;是一家怎样的公司 阿里巴巴在中国看上去很高大上&a…