A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

CharArrayReader实现一个可用作字符输入流的字符缓冲区。支持mark/set。

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

CharArrayReaderpublic class CharArrayReader extends Reader {    /** 字符缓冲区 */    protected char buf[];    /** 缓冲区中下一个被获取的字符的索引 */    protected int pos;    /** The position of mark in buffer. */    protected int markedPos = 0;    /** 字符缓冲区大小 **/    protected int count;    /**     * 根据指定的char数组创建一个CharArrayReader。     *      * buf不是复制得到的     */    public CharArrayReader(char buf[]) {        this.buf = buf;        this.pos = 0;        this.count = buf.length;    }    /**     * 根据指定的char数组创建一个CharArrayReader。     *     * @throws IllegalArgumentException 如果offset为负或大于buf.length,或者length为负,或者这两个值的和为负。     *     * @param buf       输入缓冲区(不是复制得到的)     * @param offset    要读取的第一个char在buf中的索引/偏移量     * @param length    要读取的char数目     */    public CharArrayReader(char buf[], int offset, int length) {        //如果offset为负或大于buf.length,或者length为负,或者这两个值的和为负,抛出IllegalArgumentException。        if ((offset < 0) || (offset > buf.length) || (length < 0) ||            ((offset + length) < 0)) {            throw new IllegalArgumentException();        }        this.buf = buf;        this.pos = offset;        //count为length或buf.length-offset其中的较小者        this.count = Math.min(offset + length, buf.length);        this.markedPos = offset;    }    /** 检查流是否被关闭。若字符缓冲为null,则认为流已关闭。*/    private void ensureOpen() throws IOException {        if (buf == null)            throw new IOException("Stream closed");    }    /**     * 读取单个字符。     * 如果到达缓冲区末尾,返回-1     */    public int read() throws IOException {        synchronized (lock) {            ensureOpen();            if (pos >= count)                return -1;            else                return buf[pos++];        }    }    /**     * 读取数据,并保存到字符数组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;            }            if (pos >= count) {                return -1;            }            if (pos + len > count) {                len = count - pos;            }            if (len <= 0) {                return 0;            }            System.arraycopy(buf, pos, b, off, len);            pos += len;            return len;        }    }    /**     * 跳过字符。     * 返回跳过的字符数。     */    public long skip(long n) throws IOException {        synchronized (lock) {            ensureOpen();            if (pos + n > count) {                n = count - pos;            }            if (n < 0) {                return 0;             }            pos += n;            return n;        }    }    /**     * 判断此流是否已准备好被读取。     */    public boolean ready() throws IOException {        synchronized (lock) {            ensureOpen();            return (count - pos) > 0;        }    }    /**     * 判断此流是否支持mark()操作     * CharArrayReader支持mark()操作。     *      */    public boolean markSupported() {        return true;    }    /**     * 标记流中的当前位置。     * 对reset()的后续调用会将该流重新定位到此点。     */    public void mark(int readAheadLimit) throws IOException {        synchronized (lock) {            ensureOpen();            markedPos = pos;        }    }    /**     * 将该流重置为最新的标记。     * 如果从未标记过,则将其重置到开头。     *     * @exception  IOException  If an I/O error occurs     */    public void reset() throws IOException {        synchronized (lock) {            ensureOpen();            pos = markedPos;        }    }    /**     * 关闭该流并释放与之关联的所有系统资源。     */    public void close() {        buf = null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
demoimport java.io.CharArrayReader;import java.io.IOException;import org.junit.Test;public class CharArrayReaderTest {    /**     * CharArrayReader的API测试函数     */    @Test    public void tesCharArrayReader() {        try {            CharArrayReader reader = new CharArrayReader(                    new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' });            // 从reader中连续读取三个字节            for (int i = 0; i < 3; i++) {                if (reader.ready() == true) {                    char tmp = (char) reader.read();                    System.out.print(tmp);                }            }            System.out.println();            // 测试是否支持mark            if (!reader.markSupported()) {                System.out.println("make not supported!");                return;            } else                System.out.println("make supported!");            // 标记,当前位置为d            reader.mark(0);            // 跳过2个字符,当前位置为f            reader.skip(2);            // 向下读取两个字符,fg            char[] buf = new char[2];            reader.read(buf, 0, 2);            System.out.println("buf:" + String.valueOf(buf));            // 重置当前位置为上一次标记的位置,即为d            reader.reset();            // 向下读取两个字符,de            reader.read(buf, 0, 2);            System.out.println("buf:" + String.valueOf(buf));            // 关闭后,在调用方法,会抛出“java.io.IOException: Stream closed”异常            reader.close();            reader.read();        } catch (IOException e) {            e.printStackTrace();        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

执行方法后,控制台打印结果为:

abcmake supported!buf:fgbuf:dejava.io.IOException: Stream closed
  • 1
  • 2
  • 3
  • 4
  • 5
总结
  • CharArrayReader实现一个可用作字符输入流的字符缓冲区。
  • 在做所有操作前,都要确认流处于open状态。判断流处于open状态的依据是buf不为null。close方法中会将buf置为null。
  • CharArrayReader支持mark()操作。
CharArrayWriterpublic class CharArrayWriter extends Writer {    /**     * 存储数据的字符缓冲区     */    protected char buf[];    /**     * 缓冲区中的字符个数     */    protected int count;    /**     * 创建一个新的CharArrayWriter。     * 缓冲区大小默认为32     */    public CharArrayWriter() {        this(32);    }    /**     * 创建一个新的CharArrayWriter,指定缓冲区大小为initialSize     * 如果initialSize为负数,抛出异常     */    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] = (char)c;            count = newcount;        }    }    /**     * 将字符数组c中从off开始的len个字符写入到缓冲区中。     */    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;            //如果buf存满、则将buf容量扩大1倍、并将原来buf中count字符copy到新的buf中             if (newcount > buf.length) {                buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));            }            System.arraycopy(c, off, buf, count, len);            count = newcount;        }    }    /**     * 将字符串str中从索引off开始的len个字符写入到缓冲区中。     */    public void write(String str, int off, int len) {        synchronized (lock) {            int newcount = count + len;            //如果buf存满、则将buf容量扩大1倍、并将原来buf中count字符copy到新的buf中             if (newcount > buf.length) {                buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));            }            str.getChars(off, off + len, buf, count);            count = newcount;        }    }    /**     * 将缓冲区的内容写入另一个字符流out。     */    public void writeTo(Writer out) throws IOException {        synchronized (lock) {            out.write(buf, 0, count);        }    }    /**     * 将指定的字符序列添加到此writer。     */    public CharArrayWriter append(CharSequence csq) {        String s = (csq == null ? "null" : csq.toString());        write(s, 0, s.length());        return this;    }    /**     * 将指定字符序列的子序列添加到此 writer。     * @since  1.5     */    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;    }    /**     * 将指定字符添加到此writer。     * @since 1.5     */    public CharArrayWriter append(char c) {        write(c);        return this;    }    /**     * 重置该缓冲区,以便再次使用它而无需丢弃已分配的缓冲区。     */    public void reset() {        count = 0;    }    /**     * 返回输入数据的副本。     */    public char toCharArray()[] {        synchronized (lock) {            return Arrays.copyOf(buf, count);        }    }    /**     * 返回缓冲区的当前大小。     */    public int size() {        return count;    }    /**     * 将输入数据转换为字符串。     */    public String toString() {        synchronized (lock) {            return new String(buf, 0, count);        }    }    /**     * 刷新该流的缓冲。     */    public void flush() { }    /**     * 关闭该流。     * 该方法无效     */    public void close() { }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
deomimport java.io.CharArrayWriter;import java.io.IOException;import org.junit.Test;public class CharArrayWriterTest {    private static final char[] charArr = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g'};    /**     * CharArrayWriter的API测试函数     */    @Test    public void testCharArrayWriter() {        try {            // 创建CharArrayWriter字符流,默认大小为32            CharArrayWriter writer = new CharArrayWriter();            writer.write('A');            writer.write("BCDEF");            writer.write(charArr, 1, 3);            System.out.println("写入字符A,写入字符串BCDEF,写入charArr中从索引位置1开始的三个字符,即bcd,此时的writer为:\n" + writer);            writer.append('0').append("12345").append(String.valueOf(charArr), 3, 6);            System.out.println("写入字符0,写入字符串12345,写入charArr中从索引位置3到5的三个字符,即def,此时的writer为:\n" + writer);            System.out.println("此时writer的大小为:\n" + writer.size());            char[] buf = writer.toCharArray();            System.out.println("将writer转化为字符数组再将其打印:\n" + String.valueOf(buf));            // 创建CharArrayWriter字符流,指定大小为100            CharArrayWriter writer2 = new CharArrayWriter(100);            writer.writeTo(writer2);            System.out.println("将writer缓冲区内容写入到wirter2中,writer缓冲区内容为:\n" + writer2);            writer.reset();            System.out.println("将writer重置,此时其缓冲区为:\n" + writer);            writer2.close();            System.out.println("将writer2关闭,调用其size方法,结果为:\n" + writer2.size());            System.out.println("如果没有抛出异常,说明其close方法没有作用。");        } catch (IOException e) {            e.printStackTrace();        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

执行方法后,控制台打印内容为:

写入字符A,写入字符串BCDEF,写入charArr中从索引位置1开始的三个字符,即bcd,此时的writer为:ABCDEFbcd写入字符0,写入字符串12345,写入charArr中从索引位置35的三个字符,即def,此时的writer为:ABCDEFbcd012345def此时writer的大小为:18将writer转化为字符数组再将其打印:ABCDEFbcd012345def将writer缓冲区内容写入到wirter2中,writer缓冲区内容为:ABCDEFbcd012345def将writer重置,此时其缓冲区为:将writer2关闭,调用其size方法,结果为:18如果没有抛出异常,说明其close方法没有作用。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
总结
  • CharArrayWriter实现一个可用作字符输出流的字符缓冲区。
  • CharArrayWriter的缓冲区会随向流中写入数据而自动增长。
  • 可使用CharArrayWritert的oCharArray()和 toString()获取缓冲区中数据。
  • CharArrayWriter中close()方法无效。

关于CharArrayReader与CharArrayWriter就讲到这里,想了解更多内容请参考

版权声明


1 个回复

倒序浏览

很不错,受教了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马