Java™ 教程(資料流)

博弈發表於2019-01-19

資料流

資料流支援原始資料型別值(booleancharbyteshortintlongfloatdouble)以及String值的二進位制I/O,所有資料流都實現DataInput介面或DataOutput介面,本節重點介紹這些介面最廣泛使用的實現,DataInputStreamDataOutputStream

DataStreams示例通過寫出一組資料記錄,然後再次讀取它們來演示資料流,每條記錄包含三個與發票上的條目相關的值,如下表所示:

訂單記錄 資料型別 資料描述 輸出方法 輸入方法 樣例值
1 double 條目價格 DataOutputStream.writeDouble DataInputStream.readDouble 19.99
2 int 單位數 DataOutputStream.writeInt DataInputStream.readInt 12
3 String 條目描述 DataOutputStream.writeUTF DataInputStream.readUTF “Java T-Shirt”

我們來看看DataStreams中的關鍵程式碼,首先,程式定義了一些常量,包含資料檔案的名稱和將寫入的資料:

static final String dataFile = "invoicedata";

static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
static final int[] units = { 12, 8, 13, 29, 50 };
static final String[] descs = {
    "Java T-shirt",
    "Java Mug",
    "Duke Juggling Dolls",
    "Java Pin",
    "Java Key Chain"
};

然後DataStreams開啟輸出流,由於DataOutputStream只能作為現有位元組流物件的包裝器建立,因此DataStreams提供緩衝檔案輸出位元組流。

out = new DataOutputStream(new BufferedOutputStream(
              new FileOutputStream(dataFile)));

DataStreams寫出記錄並關閉輸出流。

for (int i = 0; i < prices.length; i ++) {
    out.writeDouble(prices[i]);
    out.writeInt(units[i]);
    out.writeUTF(descs[i]);
}

writeUTF方法以UTF-8的修改形式寫出String值,這是一種可變寬度的字元編碼,普通的西方字元只需要一個位元組。

現在DataStreams再次讀回資料,首先,它必須提供輸入流和變數來儲存輸入資料,與DataOutputStream一樣,DataInputStream必須構造為位元組流的包裝器。

in = new DataInputStream(new
            BufferedInputStream(new FileInputStream(dataFile)));

double price;
int unit;
String desc;
double total = 0.0;

現在,DataStreams可以讀取流中的每條記錄,報告它遇到的資料。

try {
    while (true) {
        price = in.readDouble();
        unit = in.readInt();
        desc = in.readUTF();
        System.out.format("You ordered %d" + " units of %s at $%.2f%n",
            unit, desc, price);
        total += unit * price;
    }
} catch (EOFException e) {
}

請注意,DataStreams通過捕獲EOFException來檢測檔案結束條件,而不是測試無效的返回值,DataInput方法的所有實現都使用EOFException而不是返回值。

另請注意,DataStream中的每個專用write都與相應的專用read完全匹配,程式設計師應該確保以這種方式匹配輸出型別和輸入型別:輸入流由簡單的二進位制資料組成,沒有指示單個值的型別或它們在流中開始的位置。

DataStreams使用一種非常糟糕的程式設計技術:它使用浮點數來表示貨幣值,通常,浮點對於精確值是不利的,對於小數部分尤其不好,因為常見值(例如0.1)沒有二進位制表示。

用於貨幣值的正確型別是java.math.BigDecimal,不幸的是,BigDecimal是一種物件型別,因此它不適用於資料流,但是,BigDecimal將使用物件流,這將在下一節中介紹。


上一篇:命令列I/O

下一篇:物件流

相關文章