Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13
轉載自? ?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簡介:
A:關鍵字
protected char buf[]; 用于存放寫入CharArrayWriter的字符、存滿自動擴容。 protected int count; buf中現有的字符數B:構造方法
public CharArrayWriter() 使用默認buf大小創建CharArrayWriter。 public CharArrayWriter(int initialSize) 使用指定的buf大小創建CharArrayWriter。?C:一般方法
CharArrayWriter append(CharSequence csq) 將一串有序字符序列寫入buf中 CharArrayWriter append(CharSequence csq, int start, int end) 將一串有序字符序列的一部分寫入buf中 CharArrayWriter append(char c) 將一個字符寫入buf中 void close() 關閉此流(沒有效果) void flush() flush此流(沒有效果) void reset() 清空buf、重頭開始 int size() 查看當前buf中字符總數 char[] toCharArray() 將buf中內容轉換成char[] String toString() 將buf中字符轉換成String返回 void write(int c) 寫入一個字符。 void write(char c[], int off, int len) 將一個char[]的一部分寫入buf中、若buf滿、擴容。 void write(String str, int off, int len) 將一個字符串寫入buf中、滿自動擴容 void writeTo(Writer out) 將buf中現有的字節寫入到subWriter(out)中3、源碼分析
package com.chy.io.original.code; import java.io.IOException; import java.util.Arrays; /** * Writer的一個子類、可將字符寫入到自帶的一個緩存字符數組buf中、 * 當buf寫滿時、會自動擴容。 */ public class CharArrayWriter extends Writer { /** * 用于存放寫入CharArrayWriter的字符、存滿自動擴容。 */ protected char buf[]; /** * buf中現有的字符數 */ protected int count; /** * 使用默認buf大小創建CharArrayWriter。 */ public CharArrayWriter() { this(32); } /** * 使用指定的buf大小創建CharArrayWriter。 */ 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個下標位置。 buf[count] = (char)c; count = newcount; } } /** * 將一個char[]的一部分寫入buf中、若buf滿、擴容。 */ 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; if (newcount > buf.length) { buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } System.arraycopy(c, off, buf, count, len); count = newcount; } } /** * 將一個字符串寫入buf中、滿自動擴容 */ public void write(String str, int off, int len) { synchronized (lock) { int newcount = count + len; if (newcount > buf.length) { buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } str.getChars(off, off + len, buf, count); count = newcount; } } /** * 將buf中現有的字節寫入到subWriter(out)中 */ public void writeTo(Writer out) throws IOException { synchronized (lock) { out.write(buf, 0, count); } } /** * 將一串有序字符序列寫入buf中 */ public CharArrayWriter append(CharSequence csq) { String s = (csq == null ? "null" : csq.toString()); write(s, 0, s.length()); return this; } /** * 將一串有序字符序列的一部分寫入buf中 */ 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; } /** * 將一個字符寫入buf中 */ public CharArrayWriter append(char c) { write(c); return this; } /** * 清空buf、重頭開始 */ public void reset() { count = 0; } /** * 將buf中內容轉換成char[] */ public char toCharArray()[] { synchronized (lock) { return Arrays.copyOf(buf, count); } } /** * 查看當前buf中字符總數 */ public int size() { return count; } /** * 將buf中字符轉換成String返回 */ public String toString() { synchronized (lock) { return new String(buf, 0, count); } } /** * flush CharArrayWriter、因此方法對CharArrayWriter沒有效果、所以方法體是空! */ public void flush() { } /** * 同樣、關閉CharArrayWriter沒有用、調用close()關閉此流、此流的方法一樣能用。 */ public void close() { } }4、實例演示:
package com.chy.io.original.test; import java.io.BufferedReader; import java.io.CharArrayReader; import java.io.CharArrayWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; /** * * @author andyChen * @version 1.1 , 13/11/15 * */ public class CharArrayTest { private static final String str = "abcdefghijklmnopqrstuvwxyz"; private static char[] charArray = new char[26]; static{ for(int i=0; i<str.length(); i++){ charArray[i] = str.charAt(i); } } private static void testCharArrayReader() throws IOException{ CharArrayReader car = new CharArrayReader(charArray); if(!car.ready()){ return; } /** * 與ByteArrayInputStream差不多、區別就是一個字節一個字符。 * 不爽的地方在于CharArrayReader沒有提供 car.available()方法、不能隨時知道buf中還有多少可以讀取的字符. */ //將寫入CharArrayReader內置字符緩存數組buf中的第一個字符輸出、并且標記buf下一個可讀字符索引的pos++ System.out.println((char)car.read()); //讀取CharArrayReader中buf字符、返回實際讀取的字符數。 char[] buf = new char[5]; car.read(buf, 0, 5); printChar(buf); //標記當前CharArrayReader流的位置、當下次調用reset后繼續使用CharArrayReader讀取時從此標記的位置開始讀取。 //即用 markedPos記錄當前的pos car.mark(0); //丟棄從buf下一個將要讀取的字符開始的10個字符、返回實際丟棄的字符。 car.skip(10); //讀取10個字符 char[] buf2 = new char[10]; car.read(buf2, 0, 10); printChar(buf2); //查看buf中是否還有有效可供讀取的字符 System.out.println(car.ready()); //重置mark標記的位置、即將markedPos的值重新賦給pos、這樣當讀取下一個字符時就是讀取buf的索引為pos的字符。 car.reset(); System.out.println((char)car.read()); } private static void testCharArrayWriter() throws IOException{ File file = new File("D:\\caw.txt"); CharArrayWriter caw = new CharArrayWriter(); //將第一個 a-z 字符寫入caw內置buf中 for(int i=0; i<charArray.length; i++){ caw.write(charArray[i]); } caw.write("\r\n"); //將第二個a-z字符寫入caw內置buf中 caw.write(charArray, 0, charArray.length); caw.write("\r\n"); //將第三個a-z字符寫入buf中 caw.write(charArray); caw.write("\r\n"); //將第四個a-z字符寫入buf中 caw.write(new String(charArray), 0, charArray.length); caw.write("\r\n"); //將第五個a-z字符寫入buf中 for(int i=0; i<charArray.length; i++){ caw.append(charArray[i]); } caw.append("\r\n"); //此方法傳入的是一個CharSequence、CharArray是一個CharSequence的一個子類、但是為什么不行? //caw.append(charArray); //caw.append("\r\n"); //將第六個a-z字符寫入buf中 caw.append(new StringBuffer(new String(charArray))); caw.append("\r\n"); /** * 簡單說明:caw.append()傳入的參數時CharSequence、char * 但是上面傳入的String、StringBuffer、StringBuilder也行、很簡單、他們是CharSequence接口的實現類。 */ String aboveResult = caw.toString(); char[] buf = caw.toCharArray(); System.out.println("String aboveResult: "+ "\r\n" + aboveResult); System.out.println("====================================="); System.out.println("char[] result : " + "\r\n" +new String(buf)); FileWriter fw = new FileWriter(file); caw.writeTo(fw); fw.flush(); fw.close(); } /** * 將寫入文件的中文讀取出來 * 這里沒有什么組織性、 * 自己可以嘗試不同組合的讀取、加深理解。 */ private static void test() throws FileNotFoundException, IOException { File file = new File("D:\\bos.txt"); FileOutputStream fos = new FileOutputStream(file); FileInputStream fis = new FileInputStream(file); fos.write("陳華應".getBytes()); fos.flush(); fos.close(); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); char[] cbuf = new char[fis.available()]; br.read(cbuf); CharArrayReader car = new CharArrayReader(cbuf); char[] newCbuf = new char[fis.available()]; car.read(newCbuf); System.out.println(new String (newCbuf)); } private static void printChar(char[] buf){ for(char c : buf ){ System.out.print(c); } System.out.println(); } public static void main(String[] args) throws Exception{ testCharArrayWriter(); testCharArrayReader(); test(); } }總結:
? ? ? ? ? ? 本質是將字符寫入內置字符緩存數組中、或者是將字符從內置緩存數組讀取到程序中(內置字符緩存數組中字符的來源是在構造CharArrayReader時傳入的字符數組)。
總結
以上是生活随笔為你收集整理的Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 目标 100% 平等,斯宾塞强调不会利用
- 下一篇: 马斯克的X测试“不是机器人”计划,新用户