数据流支持基本数据类型值( booleancharbyteshortintlongfloatdouble),以及字符串值的二进制I / O。所有数据流都实现 DataInput接口或 DataOutput接口。本节主要介绍这些接口的最广泛使用的实现, DataInputStreamDataOutputStream
    DataStreams示例通过写出一组数据记录,然后再次读取它们来演示数据流。每个记录由与发票项目相关的三个值组成,如下表所示:

    记录中的顺序 数据类型 数据说明 输出方法 输入方法 样本值
    1 double 商品价格
    (Item price)
    DataOutputStream.writeDouble DataInputStream.readDouble 19.99
    2 int 单位数
    (Unit count)
    DataOutputStream.writeInt DataInputStream.readInt 12
    3 String 商品描述
    (Item description)
    DataOutputStream.writeUTF DataInputStream.readUTF "Java T-Shirt"

    让我们检查DataStreams中的关键代码。首先,程序定义了一些常量,这些常量包含数据文件的名称以及将要写入其中的数据:

    1. static final String dataFile = "invoicedata";
    2. static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
    3. static final int[] units = { 12, 8, 13, 29, 50 };
    4. static final String[] descs = {
    5. "Java T-shirt",
    6. "Java Mug",
    7. "Duke Juggling Dolls",
    8. "Java Pin",
    9. "Java Key Chain"
    10. };

    然后DataStreams打开一个输出流。由于只能将DataOutputStream创建为现有字节流对象的包装,因此DataStreams提供了一个缓冲的文件输出字节流。

    1. out = new DataOutputStream(new BufferedOutputStream(
    2. new FileOutputStream(dataFile)));

    DataStreams 写出记录并关闭输出流。

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

    writeUTF方法以UTF-8的修改形式写出String值。这是一种可变宽度的字符编码,对于常见的西方字符仅需要一个字节。
    现在DataStreams再次读回数据。首先,它必须提供输入流和变量以保存输入数据。与DataOutputStream一样,DataInputStream必须构造为字节流的包装器。

    1. in = new DataInputStream(new
    2. BufferedInputStream(new FileInputStream(dataFile)));
    3. double price;
    4. int unit;
    5. String desc;
    6. double total = 0.0;

    现在DataStreams可以读取流中的每条记录,报告其遇到的数据。

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

    注意,DataStreams通过捕获EOFException来检测文件结束条件,而不是测试无效的返回值。DataInput方法的所有实现都使用EOFException而不是返回值。
    还要注意,DataStreams中的每个专用write都与相应的专用read完全匹配。 程序员应确保以这种方式匹配输出类型和输入类型:输入流由简单的二进制数据组成,没有任何内容可以指示单个值的类型或它们在流中的起始位置。
    DataStreams使用一种非常糟糕的编程技术:它使用浮点数来表示货币值。通常,浮点数对精确值不利。对于十进制小数,这尤其糟糕,因为一般值(例如0.1)没有二进制表示形式。
    用于货币值的正确类型是 java.math.BigDecimal。不幸的是,BigDecimal是一种对象类型,因此它不适用于数据流。但是,BigDecimal 与对象流一起使用,这将在下一节中介绍。