1. 程式人生 > 其它 >【IO程式設計】3.位元組流和字元流

【IO程式設計】3.位元組流和字元流

1. FileInputStream介紹

  • 構造方法
    • FileInputStream(String name)
      • name: 檔名
    • FileInputStream(File file)
      • file: 檔案
  • 成員方法
    • int read(byte[] buf)
      • 批量讀取位元組到陣列中,返回讀取到的位元組數,如果到檔案末尾返回-1
    • int read()
      • 讀取一個位元組
    • void close()
      • 關閉流,需要捕獲IO異常

使用FileInputStream讀取檔案,注意流關閉時也需要捕獲IOException

@Test
public void readFile1() {
    FileInputStream fis = null;
    int readData = -1;
    try {
        // FileNotFoundException 如果找不到該檔案就丟擲異常
        fis = new FileInputStream("E:\\test.txt");
        // read() 方法會丟擲IO異常
        while ((readData = fis.read()) != -1) {
            System.out.print((char)readData);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fis != null) {
            try {
                // 流關閉時需要捕獲IOException
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

以上方式沒有加快取,讀取效率低。可以增加一個byte陣列作為快取來提高效率,並且需要一個值去記錄讀取資料的長度。程式碼如下:

@Test
public void readFile2() {
    FileInputStream fis = null;
    // 位元組陣列,當作快取來提高讀取效率
    byte[] buffer = new byte[4];
    // 讀取資料的長度
    int readLength = 0;
    try {
        // FileNotFoundException 如果找不到該檔案就丟擲異常
        fis = new FileInputStream("E:\\test.txt");
        // read() 方法會丟擲IO異常
        while ((readLength = fis.read(buffer)) != -1) {
            System.out.print(new String(buffer, 0, readLength));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2. FileOutputStream介紹

  • 構造方法

    • FileOutputStream(String name)
      • name為檔名,呼叫此方法建立的物件將以覆蓋的方式寫檔案
    • FileOutputStream(File file)
    • FileOutputStream(String name, boolean append)
      • name為檔名,append為是否為追加方式
      • append為false是以覆蓋的方式寫檔案,為true是以追加的方式寫檔案
    • FileOutputStream(File file, boolean append)
  • 成員方法

    • write(int b)
      • 寫入一個位元組b
    • write(byte[] b)
      • 寫入一個位元組陣列b
    • write(byte[] b, int off, int len)
      • 寫入一個位元組陣列b,且從索引off開始,長度為len
    • void close()
      • 關閉流,需要捕獲IO異常

將字串內容寫入到檔案中,程式碼如下:

@Test
public void writeFile1() {
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream("e:\\test.txt");
        String str = "hello, world";
        fos.write(str.getBytes());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3. 使用FileInputStream和FileOutputStream實現檔案拷貝

實現思路為每次用FileInputStream讀取資料後立即使用FileOutputStream將這部分資料寫入到一個新檔案中。程式碼如下:

public boolean copyFile(String sourceFilePath, String destFilePath) {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    byte[] buffer = new byte[1024];
    int readLength = 0;
    boolean success = false;

    try {
        fis = new FileInputStream(sourceFilePath);
        fos = new FileOutputStream(destFilePath);
        while ((readLength = fis.read(buffer)) != -1) {
            fos.write(buffer, 0, readLength);
        }
        success = true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (fis != null) {
                fis.close();
            }
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return success;
}

4. FileReader介紹

  • 構造方法
    • FileReader(String filename)
    • FileReader(File file)
  • 成員方法
    • int read()
      • 讀取單個字元,如果到檔案末尾返回-1
    • int read(char[] cbuf)
      • 批量讀取字元到陣列中,返回讀取到的字元數,如果到檔案末尾返回-1
    • void close()
      • 關閉流,需要捕獲IO異常

使用FileReader讀取檔案

@Test
public void readFile() {
    FileReader fr = null;
    char[] buffer = new char[4];
    int readLength = 0;
    try {
        fr = new FileReader("e:\\test.txt");
        while ((readLength = fr.read(buffer)) != -1) {
            System.out.print(new String(buffer, 0, readLength));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fr != null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5. FileWriter介紹

  • 構造方法
    • FileWriter(String filename)
    • FileWriter(File file)
    • FileWriter(String file, boolean append)
    • FileWriter(File file, boolean append)
    • 使用FileWriter(String filename)或FileWriter(File file)建立的物件是以覆蓋的方式寫檔案。對於FileWriter(String file, boolean append)和FileWriter(File file, boolean append)而言,當append為true是為追加的方式寫檔案,為false是以覆蓋的方式寫檔案。
  • 成員方法
    • write(int c)
      • 寫入單個字元
    • write(char[] cbuf)
      • 寫入指定陣列
    • write(char[] cbuf, int off, int len)
      • 寫入指定陣列的指定部分,以索引off開始,長度為len
    • write(String str)
      • 寫入指定字串
    • write(String str, int off, int len)
      • 寫入指定字串的指定部分,以索引off開始,長度為len
    • void close()
      • 關閉流,需要捕獲IO異常
  • 注意:使用FileWriter後,必須呼叫close()方法或者flush()方法,否則無法寫入內容。

使用FileWriter寫入檔案,程式碼如下:

@Test
public void writeFile() {
    FileWriter fw = null;
    try {
        fw = new FileWriter("e:\\test.txt");
        fw.write("hello, world!");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}