Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例――13(一)

2014-11-24 08:05:01 · 作者: · 浏览: 2

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