本章,我們學習CharArrayWriter。學習時,我們先對CharArrayWriter有個大致了解,然后深入了解一下它的源碼,最后通過示例來掌握它的用法。
轉載請注明出處:http://www.cnblogs.com/skywang12345/p/io_19.html
更多內容請參考:Java io系列 "目錄"
CharArrayWriter 介紹
CharArrayReader 用於寫入數據符,它繼承於Writer。操作的數據是以字符為單位!
CharArrayWriter 函數列表
CharArrayWriter() CharArrayWriter(int initialSize) CharArrayWriter append(CharSequence csq, int start, int end) CharArrayWriter append(char c) CharArrayWriter append(CharSequence csq) void close() void flush() void reset() int size() char[] toCharArray() String toString() void write(char[] buffer, int offset, int len) void write(int oneChar) void write(String str, int offset, int count) void writeTo(Writer out)
Writer和CharArrayWriter源碼分析
Writer是CharArrayWriter的父類,我們先看看Writer的源碼,然后再學CharArrayWriter的源碼。
1. Writer源碼分析(基於jdk1.7.40)

1 package java.io; 2 3 public abstract class Writer implements Appendable, Closeable, Flushable { 4 5 private char[] writeBuffer; 6 7 private final int writeBufferSize = 1024; 8 9 protected Object lock; 10 11 protected Writer() { 12 this.lock = this; 13 } 14 15 protected Writer(Object lock) { 16 if (lock == null) { 17 throw new NullPointerException(); 18 } 19 this.lock = lock; 20 } 21 22 public void write(int c) throws IOException { 23 synchronized (lock) { 24 if (writeBuffer == null){ 25 writeBuffer = new char[writeBufferSize]; 26 } 27 writeBuffer[0] = (char) c; 28 write(writeBuffer, 0, 1); 29 } 30 } 31 32 public void write(char cbuf[]) throws IOException { 33 write(cbuf, 0, cbuf.length); 34 } 35 36 abstract public void write(char cbuf[], int off, int len) throws IOException; 37 38 public void write(String str) throws IOException { 39 write(str, 0, str.length()); 40 } 41 42 public void write(String str, int off, int len) throws IOException { 43 synchronized (lock) { 44 char cbuf[]; 45 if (len <= writeBufferSize) { 46 if (writeBuffer == null) { 47 writeBuffer = new char[writeBufferSize]; 48 } 49 cbuf = writeBuffer; 50 } else { // Don't permanently allocate very large buffers. 51 cbuf = new char[len]; 52 } 53 str.getChars(off, (off + len), cbuf, 0); 54 write(cbuf, 0, len); 55 } 56 } 57 58 public Writer append(CharSequence csq) throws IOException { 59 if (csq == null) 60 write("null"); 61 else 62 write(csq.toString()); 63 return this; 64 } 65 66 public Writer append(CharSequence csq, int start, int end) throws IOException { 67 CharSequence cs = (csq == null ? "null" : csq); 68 write(cs.subSequence(start, end).toString()); 69 return this; 70 } 71 72 public Writer append(char c) throws IOException { 73 write(c); 74 return this; 75 } 76 77 abstract public void flush() throws IOException; 78 79 abstract public void close() throws IOException; 80 }
2. CharArrayWriter 源碼分析(基於jdk1.7.40)
1 package java.io; 2 3 import java.util.Arrays; 4 5 public class CharArrayWriter extends Writer { 6 // 字符數組緩沖 7 protected char buf[]; 8 9 // 下一個字符的寫入位置 10 protected int count; 11 12 // 構造函數:默認緩沖區大小是32 13 public CharArrayWriter() { 14 this(32); 15 } 16 17 // 構造函數:指定緩沖區大小是initialSize 18 public CharArrayWriter(int initialSize) { 19 if (initialSize < 0) { 20 throw new IllegalArgumentException("Negative initial size: " 21 + initialSize); 22 } 23 buf = new char[initialSize]; 24 } 25 26 // 寫入一個字符c到CharArrayWriter中 27 public void write(int c) { 28 synchronized (lock) { 29 int newcount = count + 1; 30 if (newcount > buf.length) { 31 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); 32 } 33 buf[count] = (char)c; 34 count = newcount; 35 } 36 } 37 38 // 寫入字符數組c到CharArrayWriter中。off是“字符數組b中的起始寫入位置”,len是寫入的長度 39 public void write(char c[], int off, int len) { 40 if ((off < 0) || (off > c.length) || (len < 0) || 41 ((off + len) > c.length) || ((off + len) < 0)) { 42 throw new IndexOutOfBoundsException(); 43 } else if (len == 0) { 44 return; 45 } 46 synchronized (lock) { 47 int newcount = count + len; 48 if (newcount > buf.length) { 49 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); 50 } 51 System.arraycopy(c, off, buf, count, len); 52 count = newcount; 53 } 54 } 55 56 // 寫入字符串str到CharArrayWriter中。off是“字符串的起始寫入位置”,len是寫入的長度 57 public void write(String str, int off, int len) { 58 synchronized (lock) { 59 int newcount = count + len; 60 if (newcount > buf.length) { 61 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); 62 } 63 str.getChars(off, off + len, buf, count); 64 count = newcount; 65 } 66 } 67 68 // 將CharArrayWriter寫入到“Writer對象out”中 69 public void writeTo(Writer out) throws IOException { 70 synchronized (lock) { 71 out.write(buf, 0, count); 72 } 73 } 74 75 // 將csq寫入到CharArrayWriter中 76 // 注意:該函數返回CharArrayWriter對象 77 public CharArrayWriter append(CharSequence csq) { 78 String s = (csq == null ? "null" : csq.toString()); 79 write(s, 0, s.length()); 80 return this; 81 } 82 83 // 將csq從start開始(包括)到end結束(不包括)的數據,寫入到CharArrayWriter中。 84 // 注意:該函數返回CharArrayWriter對象! 85 public CharArrayWriter append(CharSequence csq, int start, int end) { 86 String s = (csq == null ? "null" : csq).subSequence(start, end).toString(); 87 write(s, 0, s.length()); 88 return this; 89 } 90 91 // 將字符c追加到CharArrayWriter中! 92 // 注意:它與write(int c)的區別。append(char c)會返回CharArrayWriter對象。 93 public CharArrayWriter append(char c) { 94 write(c); 95 return this; 96 } 97 98 // 重置 99 public void reset() { 100 count = 0; 101 } 102 103 // 將CharArrayWriter的全部數據對應的char[]返回 104 public char toCharArray()[] { 105 synchronized (lock) { 106 return Arrays.copyOf(buf, count); 107 } 108 } 109 110 // 返回CharArrayWriter的大小 111 public int size() { 112 return count; 113 } 114 115 public String toString() { 116 synchronized (lock) { 117 return new String(buf, 0, count); 118 } 119 } 120 121 public void flush() { } 122 123 public void close() { } 124 }
說明:
CharArrayWriter實際上是將數據寫入到“字符數組”中去。
(01) 通過CharArrayWriter()創建的CharArrayWriter對應的字符數組大小是32。
(02) 通過CharArrayWriter(int size) 創建的CharArrayWriter對應的字符數組大小是size。
(03) write(int oneChar)的作用將int類型的oneChar換成char類型,然后寫入到CharArrayWriter中。
(04) write(char[] buffer, int offset, int len) 是將字符數組buffer寫入到輸出流中,offset是從buffer中讀取數據的起始偏移位置,len是讀取的長度。
(05) write(String str, int offset, int count) 是將字符串str寫入到輸出流中,offset是從str中讀取數據的起始位置,count是讀取的長度。
(06) append(char c)的作用將char類型的c寫入到CharArrayWriter中,然后返回CharArrayWriter對象。
注意:append(char c)與write(int c)都是將單個字符寫入到CharArrayWriter中。它們的區別是,append(char c)會返回CharArrayWriter對象,但是write(int c)返回void。
(07) append(CharSequence csq, int start, int end)的作用將csq從start開始(包括)到end結束(不包括)的數據,寫入到CharArrayWriter中。
注意:該函數返回CharArrayWriter對象!
(08) append(CharSequence csq)的作用將csq寫入到CharArrayWriter中。
注意:該函數返回CharArrayWriter對象!
(09) writeTo(OutputStream out) 將該“字符數組輸出流”的數據全部寫入到“輸出流out”中。
示例代碼
關於CharArrayWriter中API的詳細用法,參考示例代碼(CharArrayWriterTest.java):
1 import java.io.CharArrayReader; 2 import java.io.CharArrayWriter; 3 import java.io.IOException; 4 5 6 /** 7 * CharArrayWriter 測試程序 8 * 9 * @author skywang 10 */ 11 public class CharArrayWriterTest { 12 13 private static final int LEN = 5; 14 // 對應英文字母“abcdefghijklmnopqrstuvwxyz” 15 private static final char[] ArrayLetters = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 16 17 public static void main(String[] args) { 18 19 tesCharArrayWriter() ; 20 } 21 22 /** 23 * CharArrayWriter的API測試函數 24 */ 25 private static void tesCharArrayWriter() { 26 try { 27 // 創建CharArrayWriter字符流 28 CharArrayWriter caw = new CharArrayWriter(); 29 30 // 寫入“A”個字符 31 caw.write('A'); 32 // 寫入字符串“BC”個字符 33 caw.write("BC"); 34 //System.out.printf("caw=%s\n", caw); 35 // 將ArrayLetters數組中從“3”開始的后5個字符(defgh)寫入到caw中。 36 caw.write(ArrayLetters, 3, 5); 37 //System.out.printf("caw=%s\n", caw); 38 39 // (01) 寫入字符0 40 // (02) 然后接着寫入“123456789” 41 // (03) 再接着寫入ArrayLetters中第8-12個字符(ijkl) 42 caw.append('0').append("123456789").append(String.valueOf(ArrayLetters), 8, 12); 43 44 System.out.printf("caw=%s\n", caw); 45 46 // 計算長度 47 int size = caw.size(); 48 System.out.printf("size=%s\n", size); 49 50 // 轉換成byte[]數組 51 char[] buf = caw.toCharArray(); 52 System.out.printf("buf=%s\n", String.valueOf(buf)); 53 54 // 將caw寫入到另一個輸出流中 55 CharArrayWriter caw2 = new CharArrayWriter(); 56 caw.writeTo(caw2); 57 System.out.printf("caw2=%s\n", caw2); 58 } catch (IOException e) { 59 e.printStackTrace(); 60 } 61 } 62 }
運行結果:
caw=ABCdefgh0123456789ijkl
size=22
buf=ABCdefgh0123456789ijkl
caw2=ABCdefgh0123456789ijkl