按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
306
…………………………………………………………Page 308……………………………………………………………
DataOutputStream
File
RandomAccessFile
SequenceInputStream
特别未加改动的是 DataOutputStream,所以为了用一种可转移的格式保存和获取数据,必须沿用
InputStream和 OutputStream 层次结构。
10。7。4 一个例子
为体验新类的效果,下面让我们看看如何修改 IOStreamDemo。java示例的相应区域,以便使用Reader 和
Writer 类:
//: NewIODemo。java
// Java 1。1 IO typical usage
import java。io。*;
public class NewIODemo {
public static void main(String'' args) {
try {
// 1。 Reading input by lines:
BufferedReader in =
new BufferedReader(
new FileReader(args'0'));
String s; s2 = new String();
while((s = in。readLine())!= null)
s2 += s + 〃n〃;
in。close();
// 1b。 Reading standard input:
BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System。in));
System。out。print(〃Enter a line:〃);
System。out。println(stdin。readLine());
// 2。 Input from memory
StringReader in2 = new StringReader(s2);
int c;
while((c = in2。read()) != …1)
System。out。print((char)c);
// 3。 Formatted memory input
try {
DataInputStream in3 =
new DataInputStream(
// Oops: must use deprecated class:
new StringBufferInputStream(s2));
while(true)
System。out。print((char)in3。readByte());
} catch(EOFException e) {
System。out。println(〃End of stream〃);
307
…………………………………………………………Page 309……………………………………………………………
}
// 4。 Line numbering & file output
try {
LineNumberReader li =
new LineNumberReader(
new StringReader(s2));
BufferedReader in4 =
new BufferedReader(li);
PrintWriter out1 =
new PrintWriter(
new BufferedWriter(
new FileWriter(〃IODemo。out〃)));
while((s = in4。readLine()) != null )
out1。println(
〃Line 〃 + li。getLineNumber() + s);
out1。close();
} catch(EOFException e) {
System。out。println(〃End of stream〃);
}
// 5。 Storing & recovering data
try {
DataOutputStream out2 =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(〃Data。txt〃)));
out2。writeDouble(3。14159);
out2。writeBytes(〃That was pi〃);
out2。close();
DataInputStream in5 =
new DataInputStream(
new BufferedInputStream(
new FileInputStream(〃Data。txt〃)));
BufferedReader in5br =
new BufferedReader(
new InputStreamReader(in5));
// Must use DataInputStream for data:
System。out。println(in5。readDouble());
// Can now use the 〃proper〃 readLine():
System。out。println(in5br。readLine());
} catch(EOFException e) {
System。out。println(〃End of stream〃);
}
// 6。 Reading and writing random access
// files is the same as before。
// (not repeated here)
} catch(FileNotFoundException e) {
System。out。println(
〃File Not Found:〃 + args'1');
308
…………………………………………………………Page 310……………………………………………………………
} catch(IOException e) {
System。out。println(〃IO Exception〃);
}
}
} ///:~
大家一般看见的是转换过程非常直观,代码看起来也颇相似。但这些都不是重要的区别。最重要的是,由于
随机访问文件已经改变,所以第6 节未再重复。
第 1 节收缩了一点儿,因为假如要做的全部事情就是读取行输入,那么只需要将一个 FileReader 封装到
BufferedReader 之内即可。第 1b 节展示了封装System。in,以便读取控制台输入的新方法。这里的代码量增
多了一些,因为System。in 是一个DataInputStream,而且BufferedReader 需要一个Reader 参数,所以要
用 InputStreamReader来进行转换。
在 2 节,可以看到如果有一个字串,而且想从中读取数据,只需用一个StringReader 替换
StringBufferInputStream,剩下的代码是完全相同的。
第 3 节揭示了新 IO流库设计中的一个错误。如果有一个字串,而且想从中读取数据,那么不能再以任何形式
使用StringBufferInputStream。若编译一个涉及StringBufferInputStream 的代码,会得到一条“反对”
消息,告诉我们不要用它。此时最好换用一个 StringReader。但是,假如要象第3 节这样进行格式化的内存
输入,就必须使用 DataInputStream——没有什么“DataReader”可以代替它——而DataInputStream 很不
幸地要求用到一个 InputStream 参数。所以我们没有选择的余地,只好使用编译器不赞成的
StringBufferInputStream 类。编译器同样会发出反对信息,但我们对此束手无策(注释②)。
StringReader 替换StringBufferInputStream,剩下的代码是完全相同的。
②:到你现在正式使用的时候,这个错误可能已经修正。
第4 节明显是从老式数据流到新数据流的一个直接转换,没有需要特别指出的。在第 5 节中,我们被强迫使
用所有的老式数据流,因为DataOutputStream 和 DataInputStream 要求用到它们,而且没有可供替换的东
西。然而,编译期间不会产生任何“反对”信息。若不赞成一种数据流,通常是由于它的构建器产生了一条
反对消息,禁止我们使用整个类。但在DataInputStream 的情况下,只有readLine()是不赞成使用的,因为
我们最好为 readLine()使用一个 BufferedReader (但为其他所有格式化输入都使用一个
DataInputStream)。
若比较第5 节和 IOStreamDemo。java 中的那一小节,会注意到在这个版本中,数据是在文本之前写入的。那
是由于Java 1。1 本身存在一个错误,如下述代码所示:
//: IOBug。java
// Java 1。1 (and higher?) IO Bug