1. 程式人生 > >JavaIO簡單摘要(二)

JavaIO簡單摘要(二)

字元流

Reader:用於讀取字元流的抽象類。子類必須實現的方法只有read(char[ ],int,int)和close()

|----BufferedReader:從字元輸入流中讀取文字,緩衝各個字元,從而實現字元、陣列和行的高效讀取。可以指定緩衝區大小,或者可使用預設的大小,或者可使用預設的大小。大多數情況下,預設值就足夠大了。

|----LineNumberReader:跟蹤行號的緩衝字元輸入流。此類定義了方法 setLineNumber(int) 和 getLineNumber() ,他們可分別用於設定和獲取當前行號。

|----InputStreamReader:是位元組流通向字元流的橋樑:它使用指定的charset讀取位元組並將其解碼為字元。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平臺預設的字符集。

|----FileReader:用來讀取字元檔案的便捷類。此類的構造方法假定預設字元編碼和預設位元組緩衝區大小都是適當的。要自己指定這些值,可以先在FileInputStream上構造一個InputStreamReader。

|----CharArrayReader

|----StringReader

===================================================================================================================

Writer:寫入字元流的抽象類。子類必須實現的方法僅有write(char[ ],int,int)、flush() 和close()

|----BufferedWriter:將文字寫入字元輸出流,緩衝各個字元,從而提供單個字元、陣列和字串的高效寫入。

|----OutputStreamWriter:是字元流通向位元組流的橋樑:可使用指定的charset將要寫入流中的字元編碼轉換成位元組。它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺預設的字符集。

|----FileWriter:用來寫入字元檔案的便捷類。此類的構造方法假定預設字元編碼和預設位元組緩衝區大小都是可接受的的。要自己指定這些值,可以先在FileOutputStream上構造一個OutputStreamWriter。

|----PrintWriter

|----CharArrayWriter

|----StringWriter

===================================================================================================================

位元組流

InputStream:是表示位元組輸入流的所有類的超類

|----FileInputStream:從檔案系統中的某個檔案中獲得輸入位元組。哪些檔案可用取決於主機環境。FileInputStream用於讀取諸如影象資料之類的原始位元組流。堯都區字元流,請考慮使用FileReader

|----FilterInputStream:包含其他一些輸入流,它將這些流用作其基本資料來源,它可用直接傳輸資料或提供一些額外的功能。

|----BufferedInputStream:該類實現緩衝的輸入流。

|----Stream

|----ObjectInputStream

|----PipedInputStream

===================================================================================================================

OutputStream:此抽象類是表示輸出位元組流的所有類的超類

|----FileOutputStream:檔案輸出流是用於將資料寫入File或FileDescriptor的輸出流

|----FilterOutputStream:此類是過濾輸出流的所有類的超類

|----BufferedOutputStream:該類實現緩衝的輸出流

|----PrintStream

|----DataOutputStream

|----ObjectOutputStream

|----PipedOutputStream

===================================================================================================================

緩衝區是提高效率用的,給誰提高?

BufferedWriter:是給字元輸出流提高效率用的,那就意味著,緩衝區物件建立時,必須要現有流物件。明確要提高具體的流物件的效率。

package org.czty.io;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Created by Chris chen on 2017/8/4.
 */
public class Test5 {
    public static void main(String[] args) throws IOException {
        FileWriter fileWriter = new FileWriter("d:/buftest.txt");
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);//讓緩衝區和指定流關聯
        for (int i = 0;i < 4;i++) {
            bufferedWriter.write(i + "chris");
            bufferedWriter.newLine();//寫入一個換行符,這個換行符可以依據平臺的不同寫入不同的換行符
            bufferedWriter.flush();//對緩衝區進行重新整理,可以讓資料到目的地中
        }
        bufferedWriter.close();//關閉緩衝區,即關閉具體的流
    }
}
===================================================================================================================
BufferedReader
package org.czty.io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by Chris chen on 2017/8/4.
 */
public class Test6 {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("d:/buftest.txr");
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String line = null;
        while ((line = bufferedReader.readLine()) != null) { //readLine返回時不帶換行符的
            System.out.println(line);
        }
        bufferedReader.close();
    }
}
===================================================================================================================
//記住,只要一讀取鍵盤錄入,就用這句話
package org.czty.io;

import java.io.*;

/**
 * Created by Chris chen on 2017/8/4.
 */
public class Test7 {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));//輸出到控制檯
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            if ("over".equals(line))
                break;
            bufferedWriter.write(line.toUpperCase());//將輸入的字元轉換成大寫字元輸出
            bufferedWriter.newLine();
            bufferedWriter.flush();
        }
        bufferedReader.close();
        bufferedWriter.close();
    }
}
===================================================================================================================

流物件:其實很簡單,就是讀取和寫入。但是因為功能不同,流體系中提供N多的物件。那麼開始時,到底該用哪個物件更為合適呢?這就需要明確流的操作規律。

流的操作規律:

1、明確源和目的

資料來源:就是需要讀取,可以使用兩個體系:InputStream、Reader

資料匯:就是需要寫入,可以使用兩個體系:OutputStream、Writer

2、操作的資料是否是純文字資料

如果是:資料來源:Reader

      資料匯:Writer

如果不是:資料來源:InputStream

  資料匯:OutputStream

3、雖然確定了一個體系,但是該體系中有太多的物件,到底用哪個

明確操作的資料裝置

資料來源對應的裝置:硬碟(File),記憶體(陣列),鍵盤(System.in)

資料匯對應的裝置:硬碟(File),記憶體(陣列),控制檯(System.out)

4、需要在基本操作上附加其他功能嗎?比如緩衝

如果需要就進行裝飾

轉換流特有功能:轉換流可以將位元組轉成字元,原因在於,將獲取到的位元組通過查詢編碼表獲取到指定對應字元。

轉換流的最強功能就是基於 位元組流 + 編碼表。沒有轉換,沒有字元流

轉換流有一個子類就是操作檔案的字元流物件:

InputStreamReader

|---FileReader

OutputStreamWriter

|---FileWriter

想要操作文字檔案,必須要進行編碼轉換,而編碼轉換動作轉換流都完成了。所以操作檔案的流物件只要繼承自轉換流就可以讀取一個字元了。

但是子類有一個侷限性,就是子類中使用的編碼是固定的,是本機預設的編碼表,對於簡單中文版的系統預設編碼表是GBK。

    FileReader fileReader = new FileReader("d:/test.txt");
    InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("d:/test.txt"),"gbk");
以上兩句程式碼功能一致,如果僅僅使用平臺預設編碼表,就使用
FileReader fileReader = new FileReader("d:/test.txt");
因為簡化

如果需要制定編碼表,必須用轉換流

轉換流 = 位元組流 + 編碼表

轉換流的子類File = 位元組流 + 預設編碼表

凡是操作裝置上的文字資料,涉及編碼轉換,必須使用轉換流