2014年3月22日 星期六

Java 複習筆記 : 檔案處理

資料處理最常用的技巧就是讀取檔案與輸出檔案, 例如處理過程要記錄在 log 檔. 當然最方便是紀錄在資料庫中, 很容易搜尋, 不過像 ACCESS 2003 有 2G 的限制, 如果沒有特別的搜尋需求, 其實以檔案輸出就可以了.

Java 對於檔案是以 IO 串流方式處理, 所以必須匯入 java.io.* 類別庫 :

import java.io.*;

IO 類別庫實作了許多檔案與印表機輸入與輸出之類別, 可以處理文字檔與二進位檔 (以 byte 為單位). 其次, 所有 IO 操作指令都可能拋出例外, 因此必須放在 try catch 區塊中 :

try { //IO }
catch (IOException e) {System.out.println(e);}

一. 讀取文字檔 : 

文字檔部份主要用到 FileReader 與 FileWriter 兩個類別, 如果要指定字元集或檔案寫入方式 (append/replace), 就會使用 FileInputStream 與 FileOutputStream 類別, 這些類別都是以字元 char 為處理單位. 但是對於純文字資料處理而言, 通常會採用緩衝區來處理檔案讀寫, 以減少磁碟存取頻率加快處理速度, 這就要用到 BufferedReader 與 BufferedWriter 類別.

java.lang.Object
        |-------- java.io.Reader ---------------------- java,io.BufferedReader
        |-------- java.io.InputStreamReader ------- java.io.FileReader
        |-------- java.io.Writer ----------------------- java,io.BufferedWriter
        |-------- java.io.InputStreamWriter -------- java.io.FileWriter

如果不需指定字元集, 只要將 FileReader/FileWrtiter 物件傳給 BufferedReader/BufferedWriter 做緩衝處理, 直接使用 BufferedReader 與 BufferedWriter 來讀寫檔案即可 :

FileReader fr=new FileReader("C:\\test.txt");
BufferedReader br=new BufferedReader(fr);

然後再用 BufferedReader 的 readLine() 方法來讀取檔案中的每一行字串, 當讀完最後一行時, 再讀取就會傳回 null, 因此可用迴圈來讀取全部檔案內容 :

String line;
while ((line=br.readLine()) != null) {
  System.out.print(line);
  }

我們先準備一個文字檔 test.txt 內容如下 :


1.裘千尺
2.小龍女
3.楊過
4.公孫綠萼
5.郭靖

然後用 BufferedReader 來讀取, 如下範例 1 所示 :

測試範例 1 :  http://mybidrobot.allalla.com/javatest/file1.zip  [ 看原始碼] 

import java.io.*;
public class file1 {
  public static void main(String[] args) {
    try {
      FileReader fr=new FileReader("test.txt");
      BufferedReader br=new BufferedReader(fr);
      String line;
      while ((line=br.readLine()) != null) {
        System.out.print(line);
        }
      }
    catch (IOException e) {System.out.println(e);}
    }
  }

結果顯示 :

H:\Java\JT>java file1
1.裘千尺2.小龍女3.楊過4.公孫綠萼5.郭靖

注意, readLine() 會刪除每行末尾的跳行符號 (即 "\r\n") 後再傳回, 因此檔案中原本的五列資料用 print 輸出時全部擠在一列, 如果用 println 就會輸出五列了.

也可以用 BufferedReader 繼承自 Reader 類別的 read() 方法來讀取, 但此方法是一次讀取一個字元, 讀到檔尾時會傳回 -1, 但其傳回值型態是 int, 亦即字元的整數編碼, 因此顯示時必須用 (char) 來強制轉型才會顯示原始檔案內容, 如下列範例 2 所示 :

測試範例 2 :  http://mybidrobot.allalla.com/javatest/file2.zip  [ 看原始碼] 

import java.io.*;
public class file2 {
  public static void main(String[] args) {
    try {
      FileReader fr=new FileReader("test.txt");
      BufferedReader br=new BufferedReader(fr);
      int ch;
      while ((ch=br.read()) != -1) {
        System.out.print((char)ch);
        }
      }
    catch (IOException e) {System.out.println(e);}
    }
  }

這樣就不會像 readLine() 那樣會自動刪除列尾的跳行字元了, 即使用 print 也會輸出完整內容 :

H:\Java\JT>java file2
1.裘千尺
2.小龍女
3.楊過
4.公孫綠萼
5.郭靖

如果沒有強制轉型為 char, 就會輸出編碼值 :

H:\Java\JT>java file2
4946350322131523610131050462356740845228991310514626954369421310524620844234033216033852131053463710138742




FileWriter fw=New FileWriter("C:\\test.txt");
BufferedWriter br=new BufferedWriter(fw);

~未完待續~



沒有留言:

張貼留言