目錄:系統學習 Java IO---- 目錄,概覽html
Reader 類是 Java IO API 中全部 Reader 子類的基類。 Reader 相似於 InputStream ,除了它是基於字符而不是基於字節的。 換句話說, Reader 用於讀取文本,而 InputStream 用於讀取原始字節。java
Writer 類是 Java IO API 中全部 Writer 子類的基類。 Writer 就像一個 OutputStream ,除了它是基於字符而不是基於字節的。 換句話說,Writer 用於寫入文本,而 OutputStream 用於寫入原始字節。
Writer 一般鏈接到某些數據目標,如文件,字符數組,網絡套接字等。數組
許多應用程序使用 UTF(UTF-8或UTF-16)來存儲文本數據。 可能須要一個或多個字節來表示 UTF-8 中的單個字符。 在 UTF-16 中,每一個字符須要 2 個字節來表示。 所以,在讀取或寫入文本數據時,數據中的單個字節可能與 UTF 中的一個字符不對應。 若是隻是經過 InputStream 一次讀取或寫入 UTF-8 數據的一個字節,並嘗試將每一個字節轉換爲字符,可能不會獲得正確的文本。網絡
Reader 類可以將字節解碼爲字符。 只須要告訴Reader 要解碼的字符集。 這是在實例化 Reader 時執行的(當實例化其中一個子類時)。 一般會直接使用 Reader 子類而不是 Reader。Writer 同理。app
部分方法以下:函數
方法 | 描述 |
---|---|
void mark(int readAheadLimit) | 標記流中的當前位置。 |
int read() | 讀取單個字符。 |
int read(char[] cbuf) | 將字符讀入數組。 |
abstract int read(char[] cbuf, int off, int len) | 將字符讀入數組的某一部分。 |
int read(CharBuffer target) | 試圖將字符讀入指定的字符緩衝區。 |
boolean ready() | 判斷是否準備讀取此流。 |
具體的使用須要參考對應的子類。學習
和 InputStream 相似,若是 read() 方法返回 -1 ,則 Reader 中沒有更多數據要讀取,而且能夠關閉它。-1 做爲 int 值,而不是 -1 做爲 byte 或 char 值。編碼
InputStreamReade 類用於包裝 InputStream ,從而將基於字節的輸入流轉換爲基於字符的 Reader 。 換句話說,InputStreamReader 將 InputStream 的字節解釋爲文本而不是數字數據,是字節流通向字符流的橋樑。
爲了達到最高效率,可要考慮在 BufferedReader 內包裝 InputStreamReader。例如:線程
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
一般用於從文件(或網絡鏈接)中讀取字符,其中字節表示文本。 例如,一個文本文件,其中字符編碼爲 UTF-8 。 可使用InputStreamReader 來包裝 FileInputStream 以讀取此類文件。
一個示例以下:code
InputStream inputStream = new FileInputStream("D:\\test\\1.txt"); Reader inputStreamReader = new InputStreamReader(inputStream); int data = inputStreamReader.read(); while (data != -1) { char c = (char) data; System.out.print(c); data = inputStreamReader.read(); } inputStreamReader.close();
首先建立一個 FileInputStream ,而後將其包裝在 InputStreamReader 中。 其次,該示例經過 InputStreamReader 從文件中讀取全部字符.
注意:爲清楚起見,此處已跳過正確的異常處理。 要了解有關正確異常處理的更多信息,請轉至目錄的 Java IO 異常處理。
底層 InputStream 中的字符將使用某些字符編碼進行編碼。 此字符編碼稱爲字符集,Charset。 兩種經常使用字符集是 ASCII 和 UTF8(在某些狀況下爲UTF-16)。
默認字符集可能由於環境不一樣而不一樣,因此建議告訴 InputStreamReader 實例 InputStream 中的字符用什麼字符集進行編碼。 這能夠在 InputStreamReader 構造函數中指定,能夠只提供字符集的名字字符串,在底層會調用 Charset.forName("UTF-8")
進行轉換的。 如下是設置 InputStreamReader 使用的字符集的示例:
InputStream inputStream = new FileInputStream("D:\\test\\1.txt"); Reader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
一樣建議使用 try with resources 來關閉流。一樣,只要關閉最外層的包裝流,裏面的流會被系統自動關閉。
try(InputStreamReader inputStreamReader = new InputStreamReader(input)){ int data = inputStreamReader.read(); while(data != -) { System.out.print((char) data)); data = inputStreamReader.read(); } }
OutputStreamWriter 類用於包裝 OutputStream ,從而將基於字節的輸出流轉換爲基於字符的 Writer 。
若是須要將字符寫入文件,OutputStreamWriter 很是有用,例如編碼爲 UTF-8 或 UTF-16。 而後能夠將字符(char 值)寫入 OutputStreamWriter ,它將正確編碼它們並將編碼的字節寫入底層的 OutputStream 。
一個簡單的示例以下:
OutputStream outputStream = new FileOutputStream("D:\\test\\1.txt"); Writer outputStreamWriter = new OutputStreamWriter(outputStream); outputStreamWriter.write("Hello OutputStreamWriter"); outputStreamWriter.close();
注意:爲清楚起見,此處已跳過正確的異常處理。 要了解有關正確異常處理的更多信息,請轉至目錄的 Java IO 異常處理。
同 InputStreamReader,OutputStreamWriter 也可使用指定的字符集輸出,如:
Writer outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
參考關閉 InputStreamReader 或 Java IO 異常處理。
FileReader類使得能夠將文件的內容做爲字符流讀取。 它的工做方式與 FileInputStream 很是類似,只是 FileInputStream 讀取字節,而 FileReader 讀取字符。 換句話說,FileReader 旨在讀取文本。 取決於字符編碼方案,一個字符能夠對應於一個或多個字節。
FileReader 假定您要使用運行應用程序的計算機的默認字符編碼來解碼文件中的字節。 這可能並不老是你想要的,可是不能改變它!
若是要指定其餘字符解碼方案,請不要使用 FileReader 。 而是在 FileInputStream 上使用 InputStreamReader 。 InputStreamReader 容許您指定在讀取基礎文件中的字節時使用的字符編碼方案。
FileWriter 類能夠將字符寫入文件。 在這方面它的工做原理與 FileOutputStream 很是類似,只是 FileOutputStream 是基於字節的,而 FileWriter 是基於字符的。 換句話說,FileWriter 用於寫文本。 一個字符能夠對應於一個或多個字節,這取決於使用的字符編碼方案。
建立 FileWriter 時,能夠決定是否要覆蓋具備相同名稱的任何現有文件,或者只是要追加內容到現有文件。 能夠經過選擇使用的 FileWriter 構造函數來決定。
Writer fileWriter = new FileWriter("c:\\data\\output.txt", true); // 追加模式 Writer fileWriter = new FileWriter("c:\\data\\output.txt", false); // 默認狀況,直接覆蓋原文件
注意,只要成功 new 了一個 FileWriter 對象,沒有指定是追加模式的話,那無論有沒有調用 write() 方法,都會清空文件內容。
下面是一個讀和寫的例子:
public class FileRW { public static void main(String[] args) throws IOException { // 默認是覆蓋模式 File file = new File("D:\\test\\1.txt"); Writer writer1 = new FileWriter(file); writer1.write("string from writer1, "); writer1.close(); Writer writer2 = new FileWriter(file, true); writer2.write("append content from writer2"); writer2.close(); Reader reader = new FileReader(file); int data = reader.read(); while (data != -1) { // 將會輸出 string from writer1, append content from writer2 System.out.print((char) data); data = reader.read(); } reader.close(); } }
注意:爲清楚起見,此處已跳過正確的異常處理。 要了解有關正確異常處理的更多信息,請轉至Java IO異常處理。
其餘行爲和 InputStreamReader 差很少,就不展開講了。
PipedReader 類使得能夠將管道的內容做爲字符流讀取。 所以它的工做方式與 PipedInputStream 很是類似,只是PipedInputStream 是基於字節的,而不是基於字符的。 換句話說,PipedReader 旨在讀取文本。PipedWriter 同理。
方法 | 描述 |
---|---|
PipedReader() | 建立還沒有鏈接的 PipedReader。 |
PipedReader(int pipeSize) | 建立一個還沒有鏈接的 PipedReader,並對管道緩衝區使用指定的管道大小。 |
PipedReader(PipedWriter src) | 建立直接鏈接到傳送 PipedWriter src 的 PipedReader。 |
PipedReader(PipedWriter src, int pipeSize) | 建立一個 PipedReader,使其鏈接到管道 writer src,並對管道緩衝區使用指定的管道大小。 |
PipedWriter() | 建立一個還沒有鏈接到傳送 reader 的傳送 writer。 |
PipedWriter(PipedReader snk) | 建立傳送 writer,使其鏈接到指定的傳送 reader。 |
PipedReader 必須鏈接到 PipedWriter 才能夠讀 ,PipedWriter 也必須始終鏈接到 PipedReader 才能夠寫。就是說讀寫以前,必須先創建鏈接,有兩種方式能夠創建鏈接。
Piped piped1 = new Piped(piped2);
Piped1.connect(Piped2);
而且一般,PipedReader 和 PipedWriter 由不一樣的線程使用。 注意只有一個 PipedReader 能夠鏈接到同一個 PipedWriter ,一個示例以下:
PipedWriter writer = new PipedWriter(); PipedReader reader = new PipedReader(writer); writer.write("string form pipedwriter"); writer.close(); int data = reader.read(); while (data != -1) { System.out.print((char) data); // string form pipedwriter data = reader.read(); } reader.close();
注意:爲清楚起見,這裏忽略了正確的 IO 異常處理,而且沒有使用不一樣線程,不一樣線程操做請參考 PipedInputStream 。
正如在上面的示例中所看到的,PipedReader 須要鏈接到 PipedWriter 。 當這兩個字符流鏈接時,它們造成一個管道。 要了解有關 Java IO 管道的更多信息,請參考 管道流 PipedInputStream 部分。
ByteArrayInputStream/ByteArrayOutputStream 是對字節數組處理,CharArrayReader/CharArrayWriter 則是對字符數組進行處理,其用法是基本一致的,因此這裏略微帶過。
CharArrayReader 類能夠將 char 數組的內容做爲字符流讀取。
只需將 char 數組包裝在 CharArrayReader 中就能夠很方便的生成一個 Reader 對象。
CharArrayWriter 類能夠經過 Writer 方法(CharArrayWriter是Writer的子類)編寫字符,並將寫入的字符轉換爲 char 數組。
在寫入全部字符時,CharArrayWriter 上調用 toCharArray() 能很方便的生成一個字符數組。
方法 | 描述 |
---|---|
CharArrayReader(char[] buf) | 根據指定的 char 數組建立一個 CharArrayReader |
CharArrayReader(char[] buf, int offset, int length) | 根據指定的 char 數組建立一個 CharArrayReader |
CharArrayWriter() | 建立一個新的 CharArrayWriter ,默認緩衝區大小爲 32 |
CharArrayWriter(int initialSize) | 建立一個具備指定初始緩衝區大小的新 CharArrayWriter |
注意:設置初始大小不會阻止 CharArrayWriter 存儲比初始大小更多的字符。 若是寫入的字符數超過了初始 char 數組的大小,則會建立一個新的更大的 char 數組,並將全部字符複製到新數組中。
一個使用實例以下:
CharArrayWriter writer = new CharArrayWriter(); writer.append('H'); writer.write("ello ".toCharArray()); writer.write("World"); char[] chars = writer.toCharArray(); writer.close(); CharArrayReader reader = new CharArrayReader(chars); int data = reader.read(); while (data != -1) { System.out.print((char) data); // Hello World data = reader.read(); } reader.close();
注意:爲清楚起見,此處已跳過正確的異常處理。 要了解有關正確異常處理的更多信息,請轉至 Java IO 異常處理。