Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13
轉(zhuǎn)載自? ?Java_io體系之CharArrayReader、CharArrayWriter簡介、走進(jìn)源碼及示例——13
一:CharArrayReader
1、類功能簡介:
? ? ? ? ? ? 字符數(shù)組輸入流car?????? 、與ByteArrayInputStream相同、用于將自帶的內(nèi)置緩存字符數(shù)組中的字符讀取到程序中。與ByteArrayInputStream不同的是:當(dāng)調(diào)用car的close方法是將內(nèi)置緩存數(shù)組cbuffer設(shè)為null、而且car會拋出IOException異常(ensureOpen方法、即當(dāng)cbuffer為null時(shí)則認(rèn)為car關(guān)閉)。方法與使用功能與bais很相似、說白了區(qū)別就在于一個(gè)是從內(nèi)置字節(jié)數(shù)組中讀取字節(jié)、一個(gè)是從內(nèi)置字符數(shù)組中讀取字符。有一點(diǎn)是與bais不同的地方、就是他們的父類的區(qū)別、Reader比InputStream多實(shí)現(xiàn)一個(gè)Readable接口、這個(gè)接口要求提供一個(gè)方法、是將字符數(shù)組讀取到指定的緩存數(shù)組中、其實(shí)完全可以用read(char[] cbuf, int off, int len)來代替實(shí)現(xiàn)。。。
2、CharArrayReader? API簡介:
A:關(guān)鍵字
protected char buf[]; 自帶字符數(shù)組 protected int pos; buf中下一個(gè)要被讀取的字符位置 protected int markedPos = 0; buf中被mark的字符下標(biāo) protected int count; 字符數(shù)組中總數(shù)、buf中索引為count和下一個(gè)都沒有字符存在。B:構(gòu)造方法
CharArrayReader(char buf[]); 使用傳入的buf構(gòu)造CharArrayReader CharArrayReader(char buf[], int offset, int length); 使用傳入的buf的一部分構(gòu)造CharArrayReader?C:一般方法
void close(); 關(guān)閉此流、 void mark(int readAheadLimit); 標(biāo)記當(dāng)前流讀取的位置 void markSupport(); 檢測此流是否支持標(biāo)記 int read(); 讀取一個(gè)字符、并以整數(shù)形式返回 int read(char[] c, int off, int len); 將buf中l(wèi)en個(gè)字符讀取到下標(biāo)從off開始的b中、返回讀取的字符個(gè)數(shù) boolean ready(); 查看CharArrayReader是否可讀。 void reset(); 將此流開始位置重置到最后一次調(diào)用mark是流的讀取位置 long skip(long n); 丟棄buf中n個(gè)字符、返回實(shí)際丟棄的字符個(gè)數(shù)3、源碼分析
package com.chy.io.original.code; import java.io.IOException; /** * 字符數(shù)組輸入流 */ public class CharArrayReader extends Reader { /** 自帶字符數(shù)組 */ protected char buf[]; /** buf中下一個(gè)要被讀取的字符位置 */ protected int pos; /** buf中被mark的字符下標(biāo) */ protected int markedPos = 0; /** * 字符數(shù)組中總數(shù)、buf中索引為count和下一個(gè)都沒有字符存在。 */ protected int count; /** * 使用傳入的buf構(gòu)造CharArrayReader、并初始化CharArrayReader的buf、以及buf中將要被讀取的字符的下標(biāo)及總數(shù)。 */ public CharArrayReader(char buf[]) { this.buf = buf; this.pos = 0; this.count = buf.length; } /** * 使用傳入的buf構(gòu)造CharArrayReader、并初始化CharArrayReader的buf、以及buf中將要被讀取的字符的下標(biāo)及總數(shù)。 */ 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; } /** 檢測此流是否關(guān)閉、看此流的close()方法就能明白這個(gè)方法*/ private void ensureOpen() throws IOException { if (buf == null) throw new IOException("Stream closed"); } /** * 讀取單個(gè)字符 */ public int read() throws IOException { synchronized (lock) { ensureOpen(); if (pos >= count) return -1; else return buf[pos++]; } } /** * 將buf中l(wèi)en個(gè)字符讀取到下標(biāo)從off開始的b中、返回讀取的字符個(gè)數(shù)。 */ 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個(gè) 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個(gè)字符、返回實(shí)際丟棄的字符個(gè)數(shù)。 */ public long skip(long n) throws IOException { synchronized (lock) { ensureOpen(); //如果buf中剩余字符不夠n個(gè)、丟棄buf中現(xiàn)有所有字符 if (pos + n > count) { n = count - pos; } //傳入的n為負(fù)、不丟棄。 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; } /** * 標(biāo)記當(dāng)前buf中下一個(gè)將要被讀取的字符下標(biāo)。 * 傳入的readAheadLimit同ByteArrayInputStream一樣、無效。 */ public void mark(int readAheadLimit) throws IOException { synchronized (lock) { ensureOpen(); markedPos = pos; } } /** * 將此流開始位置重置到最后一次調(diào)用mark是流的讀取位置。 */ public void reset() throws IOException { synchronized (lock) { ensureOpen(); pos = markedPos; } } /** * 關(guān)閉、清空buf。 */ public void close() { buf = null; } }4、實(shí)例演示:
參見下面的實(shí)例演示、一般喜歡將兩者放在一個(gè)測試類中、分成兩個(gè)方法testCharArrayReader()、testCharArrayWriter()、有關(guān)聯(lián)的兩個(gè)類還會多出關(guān)聯(lián)測試、這樣有條理點(diǎn)。二:CharArrayWriter
1、類功能簡介:
? ? ? ? ? ? 字符數(shù)組輸出流caw、用于將字符寫入到內(nèi)置字符緩存數(shù)組char[] buf中、當(dāng)此數(shù)組存放滿員時(shí)會自動(dòng)擴(kuò)容、同樣與ByteArrayOutputStream相比他也提供了幾個(gè)操作buf中字符的方法、可使用 toCharArray() 和 toString() 獲取數(shù)據(jù)、還可使用writeTo(Writer out)將buf寫入到底層流中。同樣在此類上調(diào)用 close()、flush()無效,不會產(chǎn)生IOException、并且在關(guān)閉該流后仍然可以調(diào)用此類中的各個(gè)方法。
2、CharArrayWriter? API簡介:
A:關(guān)鍵字
protected char buf[]; 用于存放寫入CharArrayWriter的字符、存滿自動(dòng)擴(kuò)容。 protected int count; buf中現(xiàn)有的字符數(shù)B:構(gòu)造方法
public CharArrayWriter() 使用默認(rèn)buf大小創(chuàng)建CharArrayWriter。 public CharArrayWriter(int initialSize) 使用指定的buf大小創(chuàng)建CharArrayWriter。?C:一般方法
CharArrayWriter append(CharSequence csq) 將一串有序字符序列寫入buf中 CharArrayWriter append(CharSequence csq, int start, int end) 將一串有序字符序列的一部分寫入buf中 CharArrayWriter append(char c) 將一個(gè)字符寫入buf中 void close() 關(guān)閉此流(沒有效果) void flush() flush此流(沒有效果) void reset() 清空buf、重頭開始 int size() 查看當(dāng)前buf中字符總數(shù) char[] toCharArray() 將buf中內(nèi)容轉(zhuǎn)換成char[] String toString() 將buf中字符轉(zhuǎn)換成String返回 void write(int c) 寫入一個(gè)字符。 void write(char c[], int off, int len) 將一個(gè)char[]的一部分寫入buf中、若buf滿、擴(kuò)容。 void write(String str, int off, int len) 將一個(gè)字符串寫入buf中、滿自動(dòng)擴(kuò)容 void writeTo(Writer out) 將buf中現(xiàn)有的字節(jié)寫入到subWriter(out)中3、源碼分析
package com.chy.io.original.code; import java.io.IOException; import java.util.Arrays; /** * Writer的一個(gè)子類、可將字符寫入到自帶的一個(gè)緩存字符數(shù)組buf中、 * 當(dāng)buf寫滿時(shí)、會自動(dòng)擴(kuò)容。 */ public class CharArrayWriter extends Writer { /** * 用于存放寫入CharArrayWriter的字符、存滿自動(dòng)擴(kuò)容。 */ protected char buf[]; /** * buf中現(xiàn)有的字符數(shù) */ protected int count; /** * 使用默認(rèn)buf大小創(chuàng)建CharArrayWriter。 */ public CharArrayWriter() { this(32); } /** * 使用指定的buf大小創(chuàng)建CharArrayWriter。 */ public CharArrayWriter(int initialSize) { if (initialSize < 0) { throw new IllegalArgumentException("Negative initial size: " + initialSize); } buf = new char[initialSize]; } /** * 寫入一個(gè)字符。 */ public void write(int c) { synchronized (lock) { int newcount = count + 1; //如果buf存滿、則將buf容量擴(kuò)大1倍、并將原來buf中count字符copy到新的buf中 if (newcount > buf.length) { buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } //將新寫入的字符存入到buf第count個(gè)下標(biāo)位置。 buf[count] = (char)c; count = newcount; } } /** * 將一個(gè)char[]的一部分寫入buf中、若buf滿、擴(kuò)容。 */ 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; } } /** * 將一個(gè)字符串寫入buf中、滿自動(dòng)擴(kuò)容 */ 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中現(xiàn)有的字節(jié)寫入到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; } /** * 將一個(gè)字符寫入buf中 */ public CharArrayWriter append(char c) { write(c); return this; } /** * 清空buf、重頭開始 */ public void reset() { count = 0; } /** * 將buf中內(nèi)容轉(zhuǎn)換成char[] */ public char toCharArray()[] { synchronized (lock) { return Arrays.copyOf(buf, count); } } /** * 查看當(dāng)前buf中字符總數(shù) */ public int size() { return count; } /** * 將buf中字符轉(zhuǎn)換成String返回 */ public String toString() { synchronized (lock) { return new String(buf, 0, count); } } /** * flush CharArrayWriter、因此方法對CharArrayWriter沒有效果、所以方法體是空! */ public void flush() { } /** * 同樣、關(guān)閉CharArrayWriter沒有用、調(diào)用close()關(guān)閉此流、此流的方法一樣能用。 */ public void close() { } }4、實(shí)例演示:
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差不多、區(qū)別就是一個(gè)字節(jié)一個(gè)字符。 * 不爽的地方在于CharArrayReader沒有提供 car.available()方法、不能隨時(shí)知道buf中還有多少可以讀取的字符. */ //將寫入CharArrayReader內(nèi)置字符緩存數(shù)組buf中的第一個(gè)字符輸出、并且標(biāo)記buf下一個(gè)可讀字符索引的pos++ System.out.println((char)car.read()); //讀取CharArrayReader中buf字符、返回實(shí)際讀取的字符數(shù)。 char[] buf = new char[5]; car.read(buf, 0, 5); printChar(buf); //標(biāo)記當(dāng)前CharArrayReader流的位置、當(dāng)下次調(diào)用reset后繼續(xù)使用CharArrayReader讀取時(shí)從此標(biāo)記的位置開始讀取。 //即用 markedPos記錄當(dāng)前的pos car.mark(0); //丟棄從buf下一個(gè)將要讀取的字符開始的10個(gè)字符、返回實(shí)際丟棄的字符。 car.skip(10); //讀取10個(gè)字符 char[] buf2 = new char[10]; car.read(buf2, 0, 10); printChar(buf2); //查看buf中是否還有有效可供讀取的字符 System.out.println(car.ready()); //重置mark標(biāo)記的位置、即將markedPos的值重新賦給pos、這樣當(dāng)讀取下一個(gè)字符時(shí)就是讀取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(); //將第一個(gè) a-z 字符寫入caw內(nèi)置buf中 for(int i=0; i<charArray.length; i++){ caw.write(charArray[i]); } caw.write("\r\n"); //將第二個(gè)a-z字符寫入caw內(nèi)置buf中 caw.write(charArray, 0, charArray.length); caw.write("\r\n"); //將第三個(gè)a-z字符寫入buf中 caw.write(charArray); caw.write("\r\n"); //將第四個(gè)a-z字符寫入buf中 caw.write(new String(charArray), 0, charArray.length); caw.write("\r\n"); //將第五個(gè)a-z字符寫入buf中 for(int i=0; i<charArray.length; i++){ caw.append(charArray[i]); } caw.append("\r\n"); //此方法傳入的是一個(gè)CharSequence、CharArray是一個(gè)CharSequence的一個(gè)子類、但是為什么不行? //caw.append(charArray); //caw.append("\r\n"); //將第六個(gè)a-z字符寫入buf中 caw.append(new StringBuffer(new String(charArray))); caw.append("\r\n"); /** * 簡單說明:caw.append()傳入的參數(shù)時(shí)CharSequence、char * 但是上面?zhèn)魅氲腟tring、StringBuffer、StringBuilder也行、很簡單、他們是CharSequence接口的實(shí)現(xiàn)類。 */ 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("陳華應(yīng)".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(); } }總結(jié):
? ? ? ? ? ? 本質(zhì)是將字符寫入內(nèi)置字符緩存數(shù)組中、或者是將字符從內(nèi)置緩存數(shù)組讀取到程序中(內(nèi)置字符緩存數(shù)組中字符的來源是在構(gòu)造CharArrayReader時(shí)傳入的字符數(shù)組)。
總結(jié)
以上是生活随笔為你收集整理的Java_io体系之CharArrayReader、CharArrayWriter简介、走进源码及示例——13的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 目标 100% 平等,斯宾塞强调不会利用
- 下一篇: Java压缩技术(二) ZIP压缩——J