Java - IO - 字符流

字符流

Java提供一些字符流類,以字符爲單位讀寫數據,專門用於處理文本文件。java

字符輸入流(Reader)

java.io.Reader抽象類是表示用於讀取字符流的全部類的超類,能夠讀取字符信息到內存中。它定義了字符輸入流的基本共性功能方法。數組

  • public int read(): 從輸入流讀取一個字符。
  • public int read(char[] cbuf): 從輸入流中讀取一些字符,並將它們存儲到字符數組 cbuf中 。
  • public void close() :關閉此流並釋放與此流相關聯的任何系統資源。

FileReader類

java.io.FileReader 類是用於讀取字符文件的類。構造時使用系統默認的字符編碼和默認字節緩衝區。app

構造方法
Constructor Description
FileReader(File file) 建立一個新的 FileReader ,給定要讀取的File對象。
FileReader(String fileName) 建立一個新的 FileReader ,給定要讀取的文件的名稱。

FileReader類中沒有本身寫方法,都是繼承了父類InputStreamReader的方法。優化

image-20200519150222900

使用

使用步驟與文件字節輸入流幾乎一致!也是三種read方法編碼

方法 描述
int read() 今後輸入流中讀取一個數據字節。
int read(byte[] b) 今後輸入流中將最多 b.length 個字節的數據讀入一個 byte 數組中。
int read(byte[] b, int off, int len) 今後輸入流中將最多 len 個字節的數據讀入一個 byte 數組中。
void close() 關閉此文件輸入流並釋放與此流有關的全部系統資源。

例子code

package characterstream;

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

public class TestReader {
    public static void main(String[] args) throws IOException {
        // 1.建立FileReader對象
        FileReader fr = new FileReader("test.txt");
        // 2.使用read()方法逐個讀取字符
        int len = 0;
        while ((len = fr.read()) != -1) {
            System.out.println((char)len);
        }
        // 3.釋放資源
        fr.close();
    }
}

字符輸出流(Writer)

java.io.Writer 抽象類是表示用於寫出字符流的全部類的超類,將指定的字符信息寫出到目的地。對象

它定義了字節輸出流的基本共性功能方法。blog

  • void write(int c) 寫入單個字符。
  • void write(char[] cbuf) 寫入字符數組。
  • abstract void write(char[] cbuf, int off, int len) 寫入字符數組的某一部分,off數組的開始索引,len寫的字符個數。
  • void write(String str) 寫入字符串。
  • void write(String str, int off, int len) 寫入字符串的某一部分,off字符串的開始索引,len寫的字符個數。
  • void flush() 刷新該流的緩衝。
  • void close() 關閉此流,但要先刷新它。

FileWriter類

java.io.FileWriter 類是寫出字符到文件的便利類。構造時使用系統默認的字符編碼和默認字節緩衝區。繼承

做用:把內存中的字符數據寫入到目的文件中索引

構造方法
Constructor Description
FileWriter(File file) 建立一個新的 FileWriter,給定要讀取的File對象。
FileWriter(File file, boolean append) 給一個File對象構造一個FileWriter對象。append爲true追加內容。
FileWriter(String fileName) 建立一個新的 FileWriter,給定要讀取的文件的名稱。
FileWriter(String fileName, boolean append) 構造一個給定文件名的FileWriter對象。append爲true追加內容。
FileWriter(FileDescriptor fd) 構造與文件描述符關聯的FileWriter對象。
使用步驟
  1. 建立FileWriter對象,構造方法中綁定要寫入的目的地
  2. 使用FileWriter中的方法write,把數據寫入到內存緩衝區中(有一個字符轉成字節的過程)
  3. 使用FileWriter對象的flush方法,把內存緩衝區中的數據,刷新到文件中。!與字節輸出流的區別在此!
  4. 釋放資源(會先把內存緩衝區的數據刷新到文件再關閉資源)
package characterstream;

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

public class TestWriter {
    public static void main(String[] args) throws IOException {
        // 1. 建立FileWriter對象,構造方法中綁定要寫入的目的地
        FileWriter fw = new FileWriter("test.txt");
        // 2. 使用FileWriter中的方法write,把數據寫入到內存緩衝區中(有一個字符轉成字節的過程)
        fw.write('0');
        fw.write("\r\n");

        char[] buf = {'a', 'b', 'c', 'd', 'e'};
        fw.write(buf);
        fw.write("\r\n");

        fw.write(buf,0,3);
        fw.write("\r\n");

        fw.write("233");
        fw.write("\r\n");

        fw.write("123456",3,3);
        fw.write("\r\n");
        // 3. 使用FileWriter對象的flush方法,把內存緩衝區中的數據,刷新到文件中。!與字節輸出流的區別在此!
        fw.flush();
        // 4. 釋放資源(會先把內存緩衝區的數據刷新到文件再關閉資源)
        fw.close();
    }
}

注意文件字符輸出類能夠直接寫字符串,而文件字節輸出流須要將字符串轉成字節數組。

test.txt內容

0
abcde
abc
233
456

IO異常的處理

JDK7以前處理

以前的入門練習,咱們一直把異常拋出,而實際開發中並不能這樣處理,建議使用try...catch...finally 代碼塊,

處理異常部分,代碼使用演示:

package characterstream;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * jdk7以前的IO異常處理方式
 */
public class CopyJDK7 {
    public static void main(String[] args) {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader("data1.txt");
            fw = new FileWriter("data2.txt");

            // 注意這裏已經不是字節流,不是byte[]
            char[] bytes = new char[1024];
            int len = 0;
            while ((len = fr.read(bytes)) != -1) {
                fw.write(bytes, 0, len);
                fw.flush();
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {

            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }

            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }

    }
}

看着這麼多大括號,太影響代碼的可讀性了!

JDK7的處理(擴展知識)

JDK7優化後的try-with-resource 語句,該語句確保了每一個資源在語句結束時關閉。

所謂的資源(resource)是指在程序完成後,必須關閉的對象。

package characterstream;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * jdk7的新特性:
 * try (建立流對象語句,若是建立多個流使用';'隔開) {
 * // 讀寫數據
 * } catch (IOException e) {
 * // 異常處理
 * }
 */
public class CopyJDK7 {
    public static void main(String[] args) {
        // JDK7新特性,在try後面加個括號並在裏面定義流對象,會自動釋放資源
        try (FileReader fr = new FileReader("data1.txt");
             FileWriter fw = new FileWriter("data2.txt")) {
            // 邏輯代碼不變,定義提早
            char[] bytes = new char[1024];
            int len = 0;
            while ((len = fr.read(bytes)) != -1) {
                fw.write(bytes, 0, len);
                fw.flush();
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        
        System.out.println("複製完成");
    }
}

JDK9的也作了些改進,但很差用就不寫了

相關文章
相關標籤/搜索