|
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总结- 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中从索引位置3到5的三个字符,即def,此时的writer为:ABCDEFbcd012345def此时writer的大小为:18将writer转化为字符数组再将其打印:ABCDEFbcd012345def将writer缓冲区内容写入到wirter2中,writer缓冲区内容为:ABCDEFbcd012345def将writer重置,此时其缓冲区为:将writer2关闭,调用其size方法,结果为:18如果没有抛出异常,说明其close方法没有作用。总结- CharArrayWriter实现一个可用作字符输出流的字符缓冲区。
- CharArrayWriter的缓冲区会随向流中写入数据而自动增长。
- 可使用CharArrayWritert的oCharArray()和 toString()获取缓冲区中数据。
- CharArrayWriter中close()方法无效。
关于CharArrayReader与CharArrayWriter就讲到这里,想了解更多内容请参考 版权声明
|