JAVA篇:Java IO (七) 字符串流和数组流

7、字符串流 StringReader和StringWriter

字符串流的源是一个字符串,其读取以及写入是按照字符char来进行的。

7.1 StringReader

StringReader在构造时会传入一个字符串作为源,并且支持mark方法

    private String str;
    private int length;
    private int next = 0;//指向下一个可读取的位置
    private int mark = 0;//"书签"
   /*构造函数*/
    public StringReader(String s) {
        this.str = s;
        this.length = s.length();
    }

 

读取时按照字符读取。

    public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (next >= length)
                return -1;
            return str.charAt(next++);
        }
    }
​
    public int read(char cbuf[], int off, int len) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
                ((off + len) > cbuf.length) || ((off + len) < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
            if (next >= length)
                return -1;
            int n = Math.min(length - next, len);
            str.getChars(next, next + n, cbuf, off);
            next += n;
            return n;
        }
    }

 

7.2 StringWriter

StringWriter则可以自定义字符串缓冲区大小或者使用使用默认大小。其close()方法无效,关闭后仍可调用而不会抛出异常。

    private StringBuffer buf;/*字符串缓冲区*/public StringWriter() {
        buf = new StringBuffer();
        lock = buf;
    }
​
    public StringWriter(int initialSize) {
        if (initialSize < 0) {
            throw new IllegalArgumentException("Negative buffer size");
        }
        buf = new StringBuffer(initialSize);
        lock = buf;
    }

 

StringWriter包含各种writer和append方法,而且可以使用toString()和getBuffer()获取已经写入的数据。

 

8、数组流

如果说文件流是把文件当做数据源,那么数组流则是把内存中的某个字节/字符数组对象当做数据源,文件流包含字节数组输入流ByteArrayInputStream和字节数组输出流ByteArrayOutputStream,字符数组输入流CharArrayReader和字符数组输出流CharArrayWriter。

8.1 字节数组输入流ByteArrayInputStream

java.io.ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read方法要提供的下一个字节。

    /*内部缓冲区*/
    protected byte buf[];
    /*内部计数器*/
    protected int pos;

 

需要注意的是,关闭ByteArrayInputStream无效。此类中的方法在关闭流后仍可被调用而不会产生任何IOException。这个可以从源代码中看出来,

其构造函数只是将传入的字节数组传入到内部缓冲区,在读取的时候从缓冲区读取。而该流的close()方法什么都没有做。

    /**
     * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
     * this class can be called after the stream has been closed without
     * generating an <tt>IOException</tt>.
     */
    public void close() throws IOException {
    }

 

8.2 字节数组输出流ByteArrayOutputStream

java.io.ByteArrayOutputStream实现了一个输出流,其中的数据被写入一个byte数组,缓冲区会随着数据的不断写入而自动增长,可使用toByteArray()和toString()获取数据。同样的,关闭ByteArrayOutputStream无效。

    /*内部缓冲区*/
    protected byte buf[];
    /*缓冲区数据个数*/
    protected int count;

 

相比于字节数组输入流,字节数组输出流做了什么似乎就没那么明确了。

字节数组输入流ByteArrayInputStream做的是将一个字节数组封装进流中,然后我们通过字节数组输入流来读取该字节数组的数据。

而字节数组输出流ByteArrayOutputStream做的是,创建ByteArrayOutputStream实例的时候只创建了默认或指定大小的内部缓冲区,然后通过write方法将数据写入内部缓冲区(期间缓冲区会自动增长),可通过toString()和toByteArray()获取流中的数据,或者使用writeTo(OutputStream out)将数据写入到指定的输出流中。

 

8.3 字符数组输入流CharArrayReader

java.io.CharArrayReader实现一个可用作字符输入流的字符缓冲区。

    /** The character buffer. */
    protected char buf[];
​
    /** The current buffer position. */
    protected int pos;
​
    public CharArrayReader(char buf[]) {
        this.buf = buf;
        this.pos = 0;
        this.count = buf.length;
    }
​
    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()会将缓冲区置空,关闭流之后不可调用。

public void close() {
        buf = null;
    }

 

8.4 字符数组输出流CharArrayWriter

java.io.CharArrayWriter实现一个可用作Writer的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用toCharArray()和toString()获取数据。

该类的close()方法也是无效的,并未做任何操作。

    /**
     * Close the stream.  This method does not release the buffer, since its
     * contents might still be required. Note: Invoking this method in this class
     * will have no effect.
     */
    public void close() { }

 

 

 

posted @ 2021-08-09 17:29  l.w.x  阅读(288)  评论(0编辑  收藏  举报