Java 程式設計()  第 六章 檔案輸入/輸出運用  上一頁    下一頁

 

6-4 紀錄檔案的輸入/輸出運用

內容:

  • 6-4-1 紀錄檔案輸出格式

  • 6-4-2 範例研討:建立員工薪資資料

  • 6-4-3 自我挑戰:列印員工薪資

6-4-1 記錄檔案輸出格式

讀取紀錄檔案大多是每次讀取一筆資料,即是每次讀取檔案內的一行資料,而不論每行包含多少屬性資料。各個屬性都有自己的資料型態,因此讀取時,只好將該筆資料可為一個字串(String)。圖 6-4 是讀取紀錄檔案的基本運作模式。每次讀取一筆資料並以字串格式儲存於 inData 變數內,亦可直接輸出到螢幕上。(如何轉換成陣列變數資料,下一個範例再說明,Ex6_2_1.java

6-6 紀錄檔案整筆輸入,並整筆輸出螢幕顯示

6-4-2 範例研討:建立員工薪資資料

A)程式功能:Ex6_2.java

擴充 Ex6_1.java 程式功能。請幫志明電器製造公司建立一套人事管理系統,該系統允許輸入員工資料,並儲存於資料檔案內(Human.data)。當輸入完畢之後,再由檔案內讀出並顯示螢幕上,觀察資料是否建立正確。假設登錄員工資料包含有:員工代號(int)、姓名(String)、工作部門(String)、底薪(int)、職務加級(int);期望操作介面,以及檔案輸出結果如下:

G:\Examples\chap9\Ex6_2>java Ex6_2

是否繼續輸入員工資料 (yes/no) =>yes

***** 輸入員工資料 *****

輸入員工姓名 =>張志明

輸入所屬部門 =>製造課

輸入員工代號 =>71209

輸入員工底薪 =>40000

輸入薪資加級 =>15000

是否繼續輸入員工資料 (yes/no) =>yes

……

……

是否繼續輸入員工資料 (yes/no) =>no

** 將資料輸出到 Human.dada 檔案內 **

***** 輸出完畢 ****

 

== Human.data 讀取並顯示 ==

代號    姓名    部門    底薪    加級

71209   張志明  製造課  40000   15000

71210   羅大仙  製造課  43000   16800

71214   陳名郎  生管課  28000   12000

71219   蔡中心  倉管課  32000   17000

71242   劉新明  行銷課  28000   15000

== Human.data 輸入完畢 ==

B)製作技巧研討:

本系統包含檔案(Human.data)輸出與輸入處理,其運作情形如圖 6-5 所示。也針對檔案輸出與輸入,分別產生下列兩個物件,及其方法如下所示:

檔案名稱

String file = “Human.data”;

輸出物件

BufferedWriter data = new BufferedWriter(new FileWriter(file));

寫入方法

data.write()

關閉方法

dada.close()

輸入物件

BufferedReader data_R = new BufferedReader(new FileReader(fileID));

讀取方法

data_R.read()

關閉方法

data_R.cloas()

  6-7 範例 Ex6_2 程式架構

Ex6_2 程式運作如下:程式開始時宣告產生鍵盤(標示 (1))與輸出檔案物件(標示 (2)),以及一只儲存資料的物件陣列,接著利用 while 迴圈連續讀取多筆資料,系統也隨時存入物件陣列內。操作者輸入完畢之後後,則將物件陣列內容,一筆接一筆寫入檔案(data.write(),標示 (2))。輸出完畢後,系統再由檔案讀出(data_R.read(),標示 (3)),也一筆接一筆顯示到螢幕上(標示 (4))。

C)程式範例:

6-8 Ex6_2 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

//Ex6_2.java

/* 擴充Ex6_1程式功能,將輸出的結果寫入檔案 */

 

import java.util.Scanner;

import java.io.*;

class Employee {      /* 物件陣列的類別宣告 */

     int ID;          // 員工代號

     String name;     // 員工姓名

     String depart;   // 所屬部門

     int payment;     // 底薪

     int duty;        // 職務加級

}

 

public class Ex6_2 {

    public static void main(String args[]) throws IOException {

        Scanner keyin = new Scanner(System.in);

        Employee[] worker = new Employee[20];

 

        /* 宣告輸出檔案物件 */

        String file = "Human.data";

        BufferedWriter data = new BufferedWriter(new FileWriter(file));

        int k=0;

        String sel;

      

        /* 讀入資料並存入物件陣列內 */

        System.out.printf("是否繼續輸入員工資料 (yes/no) =>");

        sel = keyin.nextLine();

        while(sel.equals("yes") && (k <20)) {

            worker[k] = new Employee();

            System.out.printf("***** 輸入員工資料 *****\n");

            System.out.printf("輸入員工姓名 =>");

            worker[k].name = keyin.nextLine();

            System.out.printf("輸入所屬部門 =>");

            worker[k].depart = keyin.nextLine();

            System.out.printf("輸入員工代號 =>");

            worker[k].ID = keyin.nextInt();

            System.out.printf("輸入員工底薪 =>");

            worker[k].payment = keyin.nextInt();

            System.out.printf("輸入薪資加級 =>");

            worker[k].duty = keyin.nextInt();

            keyin.nextLine();                 //清除鍵盤緩衝器

            System.out.printf("是否繼續輸入員工資料 (yes/no) =>");

            sel = keyin.nextLine();

            k = k+1;

        }

      

        /* 將物件陣列內容寫入檔案內 */

        System.out.printf("** 將資料輸出到 Human.dada 檔案內 **\n");

        for (int i=0; i<k; i++) {

            data.write(worker[i].ID + "\t");  

            data.write(worker[i].name + "\t");

            data.write(worker[i].depart + "\t");

            data.write(worker[i].payment + "\t");

            data.write(worker[i].duty + "\n");

        }

        data.close();

        System.out.printf("***** 輸出完畢 ****\n");

 

        /* 檔案輸出程式, 每次讀取一筆資料 */

        System.out.printf("\n== Human.data 讀取並顯示 ==\n");

        String inData;

        File fileID = new File(file);         //開啟 Human.data 檔案

        if (fileID.exists()) {

          BufferedReader data_R = new BufferedReader(new FileReader(fileID));

            System.out.print("代號\t姓名\t部門\t底薪\t加級\n");

            while ((inData=data_R.readLine()) != null)

                System.out.printf("%s\n", inData);

            data_R.close();

        }

        else

           System.out.printf("%s 檔案讀取錯誤\n", file);

        System.out.printf("== Human.data 輸入完畢 ==\n");

   }

}

D)程式重點說明:

(1) 3~59 :與 Ex8_4.java 程式相同,功能是連續由鍵盤輸入資料,並隨時存入物件陣列內;輸入完畢後,再將物件陣列內容輸出到 Human.data 檔案內。

(2) 65 :『File fileID = new File(file);』。宣告一個檔案物件,以供輸入使用,該檔案的名稱是『String file = “Human.data"』。

(3) 66 :『if(fileID.exist()) { …}』。如果檔案開啟成功的話,則繼續讀取檔案內容;否則通知該檔案不存在。由此可見,此程式欲能正常運作需事先該檔案,無論是否已建立資料。備註:可利用下列方法(或利用記事本)建立空白檔案:

G:\Examples>copy con: Human.data

^Z

複製了         1 個檔案。

(4) 67~68 :『BufferedRead(…)』。如果檔案存在的話,則利用該檔案建立一個可供讀取的緩衝器物件,名稱為 data_R

(5) 70~71 :『while ((inData=data_R.readLine()) != null){..}』。如果利用 data_R.readLine() 方法讀取資料成功的話,則將該資料顯示到螢幕上。這裡利用 readLine() 方法讀取,表示每次由檔案內讀取一行,也隨之將該行資料輸出螢幕上。

(6) 72 :『data_R.close();』。讀取完畢後,關閉該檔案。

6-4-3 自我挑戰:列印員工薪資表

A)程式功能:PM6_2.javaEmployee.class

志明電器公司已建立完成員工薪資管理系統(Ex6_2.java),該系統允許管理者輸入員工薪資資料,並可除儲存於 Human.data 檔案內。請編寫一套程式可供列印公司所有員工的薪資表,員工資料直接由 Human.data 檔案讀取。薪資表包含員工代號、姓名、服務部門,薪資總額(= 底薪 + 職務加級)、預扣稅額(= 薪資總額 * 0.1)與應領薪資(薪資總額預扣稅額);期望操作如下:

D:\Java2_book\chap6\PM6_2>javac PM6_2.java

 

D:\Java2_book\chap6\PM6_2>dir/b

Employee.class

Human.data

PM6_2.class

 

D:\Java2_book\chap6\PM6_2>java PM6_2

== 志明電器公司  員工薪資表 ==

員工資料                薪資總額    預扣稅額  應領薪資

張志明(71209 製造課)    55000           5500    49500

羅大仙(71210 製造課)    59800           5980    53820

陳名郎(71214 生管課)    40000           4000    36000

蔡中心(71219 倉管課)    49000           4900    44100

劉新明(71242 行銷課)    43000           4300    38700

 

薪資總額 = 246800 元整  總稅額 = 24680 元整  總應額 = 222120 元整

B)製作技巧研討:

本範例最大的特點是,每筆資料由檔案讀入後,如何儲存於物件陣列內,處理方式如圖 6-6 所示。首先系統利用 readLine() 方法讀入整筆資料後儲存於 inData 變數內,該資料還是屬於字串格式(String)。接著將 inData 導入 Scanner 類別,宣告其物件(data_R),其中必須設定字串資料之中各個欄位的『分界符號』(Demiliter),再利用 Scanner 物件方法,分別讀取各欄位資料再寫入陣列物件的變數成員內。相關之物件及其方法如下:

範例:

說明:

inData=data.readLine()

由檔案讀取一筆資料。

Scanner s = new Scanner(inData).useDelimiter("\t");

宣告成 Scanner 物件並設定分界符號(\t),物件名稱為 s

worker[k].ID = s.nextInt();

讀取一整數,再存入陣列物件的變數成員內。

6-9 紀錄檔案讀入,每筆儲存於物件陣列內

C)程式片段:

6-10 PM6_2 程式架構

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

//PM6_2.java, Human.data 檔案需存在

/* Employee.class 需存在於同目錄下 */

import java.io.*;

import java.util.Scanner;

public class PM6_2 {

    public static void main(String args[]) throws IOException {

         Employee[] worker = new Employee[20];

         String file = "Human.data";

         String inData;

         int k=0;

         File fileID = new File(file);

         if (fileID.exists()) {

 

            /* Humam.data 讀取員工資料並存入 worker[] 陣列 */

            BufferedReader data = new BufferedReader(new

 FileReader(fileID));

            while ((inData=data.readLine()) != null) {

                 Scanner s = new Scanner(inData).useDelimiter("\t");

                 worker[k] = new Employee();

                 worker[k].ID = s.nextInt();

                 worker[k].name = s.next();

                 worker[k].depart = s.next();

                 worker[k].payment = s.nextInt();

                 worker[k].duty = s.nextInt();

                 k = k +1;

            }

            data.close();

 

            /* 計算並列印薪資表 */

            System.out.printf("== 志明電器公司  員工薪資表 ==\n");

            System.out.print("員工資料\t\t薪資總額\t預扣稅\t應領薪資\n");

            ……

            ……

       else

           System.out.printf("%s 檔案不存在\n", file);

   }

}

D)程式重點分析:

(1) 17~26 :『while ((inData=data.readLine()) != null) { … }』。每次讀取一筆資料,分別填入陣列物件的變數成員內。

(2) 18 :『Scanner s = new Scanner(inData).useDelimiter("\t");』。宣告產生一個 Scanner 物件,其名稱為 s,也指定欄位分界符號為『\t』。

(3) 19 :『worker[k] = new Employee();』。產生一個 Employee 物件,並填入 worker 陣列的第 k 元素(worker[k])內。

(4) 20~24 :『worker[k].ID = s.nextInt(); …』。利用 s.nextInt() 物件方法,讀取一個整數,再填入 worker[k].ID 變數成員內。

 

翻轉工作室:粘添壽

 

Java 程式設計(二) 含物件導向

 

 

翻轉電子書系列: