The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
Data streams support binary I/O of primitive data type values (数据流支持基本数据类型值(boolean
, char
, byte
, short
, int
, long
, float
, and double
) as well as String values. boolean
、char
、byte
、short
、int
、long
、float
和double
)以及字符串值的二进制I/O。All data streams implement either the 所有数据流实现DataInput
interface or the DataOutput
interface. DataInput
接口或DataOutput
接口。This section focuses on the most widely-used implementations of these interfaces, 本节重点介绍这些接口最广泛使用的实现,DataInputStream
and DataOutputStream
.DataInputStream
和DataOutputStream
。
The DataStreams
example demonstrates data streams by writing out a set of data records, and then reading them in again. DataStreams
示例通过写出一组数据记录,然后再次读取来演示数据流。Each record consists of three values related to an item on an invoice, as shown in the following table:每个记录由与发票上的项目相关的三个值组成,如下表所示:
1 | double |
DataOutputStream.writeDouble |
DataInputStream.readDouble |
19.99 | |
2 | int |
DataOutputStream.writeInt |
DataInputStream.readInt |
12 | |
3 | String |
DataOutputStream.writeUTF |
DataInputStream.readUTF |
"Java T-Shirt" |
Let's examine crucial code in 让我们研究一下DataStreams
. DataStreams
中的关键代码。First, the program defines some constants containing the name of the data file and the data that will be written to it:首先,程序定义一些常量,其中包含数据文件的名称和将写入其中的数据:
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" };
Then 然后DataStreams
opens an output stream. DataStreams
打开一个输出流。Since a 由于DataOutputStream
can only be created as a wrapper for an existing byte stream object, DataStreams
provides a buffered file output byte stream.DataOutputStream
只能作为现有字节流对象的包装器创建,因此DataStreams
提供缓冲文件输出字节流。
out = new DataOutputStream(new BufferedOutputStream( new FileOutputStream(dataFile)));
DataStreams
writes out the records and closes the output stream.DataStreams
写出记录并关闭输出流。
for (int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeInt(units[i]); out.writeUTF(descs[i]); }
The writeUTF
method writes out String
values in a modified form of UTF-8. writeUTF
方法以UTF-8的修改形式写出String
值。This is a variable-width character encoding that only needs a single byte for common Western characters.这是一种可变宽度字符编码,普通西文字符只需要一个字节。
Now 现在,DataStreams
reads the data back in again. DataStreams
再次读取数据。First it must provide an input stream, and variables to hold the input data. 首先,它必须提供一个输入流和保存输入数据的变量。Like 与DataOutputStream
, DataInputStream
must be constructed as a wrapper for a byte stream.DataOutputStream
一样,DataInputStream
必须构造为字节流的包装器。
in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile))); double price; int unit; String desc; double total = 0.0;
Now 现在DataStreams
can read each record in the stream, reporting on the data it encounters.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) { }
Notice that 请注意,DataStreams
detects an end-of-file condition by catching EOFException
, instead of testing for an invalid return value. DataStreams
通过捕获EOFException
而不是测试无效的返回值来检测文件结束条件。All implementations of DataInput
methods use EOFException
instead of return values.DataInput
方法的所有实现都使用EOFEException
而不是返回值。
Also notice that each specialized 还要注意,write
in DataStreams
is exactly matched by the corresponding specialized read
. DataStreams
中的每个专门write
都与相应的专门read
完全匹配。It is up to the programmer to make sure that output types and input types are matched in this way: The input stream consists of simple binary data, with nothing to indicate the type of individual values, or where they begin in the stream.由程序员来确保输出类型和输入类型以这种方式匹配:输入流由简单的二进制数据组成,没有任何东西来指示单个值的类型或它们在流中的起始位置。
DataStreams
uses one very bad programming technique: it uses floating point numbers to represent monetary values. DataStreams
使用了一种非常糟糕的编程技术:它使用浮点数来表示货币值。In general, floating point is bad for precise values. 一般来说,浮点不利于精确值。It's particularly bad for decimal fractions, because common values (such as 这对于小数来说尤其糟糕,因为普通值(如0.1
) do not have a binary representation.0.1
)没有二进制表示。
The correct type to use for currency values is 用于货币值的正确类型是java.math.BigDecimal
. java.math.BigDecimal
。Unfortunately, 不幸的是,BigDecimal
is an object type, so it won't work with data streams. BigDecimal
是一种对象类型,因此不能用于数据流。However, 但是,BigDecimal
will work with object streams, which are covered in the next section.BigDecimal
将处理对象流,这将在下一节中介绍。