📄 tij0114.html
字号:
DataOutputStream out2 =
<font color="#0000ff">new</font> DataOutputStream(
<font color="#0000ff">new</font> BufferedOutputStream(
<font color="#0000ff">new</font> FileOutputStream("Data.txt")));
out2.writeDouble(3.14159);
out2.writeBytes("That was pi");
out2.close();
DataInputStream in5 =
<font color="#0000ff">new</font> DataInputStream(
<font color="#0000ff">new</font> BufferedInputStream(
<font color="#0000ff">new</font> FileInputStream("Data.txt")));
BufferedReader in5br =
<font color="#0000ff">new</font> BufferedReader(
<font color="#0000ff">new</font> InputStreamReader(in5));
<font color="#009900">// Must use DataInputStream for data:</font>
System.out.println(in5.readDouble());
<font color="#009900">// Can now use the "proper" readLine():</font>
System.out.println(in5br.readLine());
} <font color="#0000ff">catch</font>(EOFException e) {
System.out.println("End of stream");
}
<font color="#009900">// 6. Reading and writing random access</font>
<font color="#009900">// files is the same as before.</font>
<font color="#009900">// (not repeated here)</font>
} <font color="#0000ff">catch</font>(FileNotFoundException e) {
System.out.println(
"File Not Found:" + args[1]);
} <font color="#0000ff">catch</font>(IOException e) {
System.out.println("IO Exception");
}
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
general, you’ll see that the conversion is fairly straightforward and the
code looks quite similar. There are some important differences, though. First
of all, since random access files have not changed, section 6 is not repeated.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Section
1 shrinks a bit because if all you’re doing is reading line input you
need only to wrap a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BufferedReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
around a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FileReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Section 1b shows the new way to wrap <A NAME="Index1257"></A><A NAME="Index1258"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>System.in</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for reading <A NAME="Index1259"></A><A NAME="Index1260"></A><A NAME="Index1261"></A>console
input, and this expands because
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>System.in</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BufferedReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
needs a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Reader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
argument, so
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InputStreamReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is brought in to perform the translation.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
section 2 you can see that if you have a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and want to read from it you just use a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StringReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
instead of a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StringBufferInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and the rest of the code is identical.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Section
3 shows a bug in the design of the new IO stream library. If you have a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and you want to read from it, you’re
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
supposed to use a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StringBufferInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
any more. When you compile code involving a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StringBufferInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor, you get a deprecation message telling you to not use it. Instead,
you’re supposed to use a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StringReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
However, if you want to do formatted memory input as in section 3, you’re
forced to use a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
– there is no “DataReader” to replace it – and a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor requires an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>InputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
argument. So you have no choice but to use the deprecated
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StringBufferInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class. The compiler will give you a deprecation message but there’s
nothing you can do about it.
</FONT><A NAME="fnB48" HREF="#fn48">[48]</A><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Section
4 is a reasonably straightforward translation from the old streams to the new,
with no surprises. In section 5, you’re forced to use all the old streams
classes because
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataOutputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
require them and there are no alternatives. However, you don’t get any
deprecation messages at compile time. If a stream is deprecated, typically its
constructor produces a deprecation message to prevent you from using the entire
class, but in the case of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
only the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>readLine( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method is deprecated since you’re supposed to use a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>BufferedReader</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>readLine( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(but a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DataInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for all other formatted input).
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you compare section 5 with that section in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>IOStreamDemo.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
you’ll notice that in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>this</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
version, the data is written
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>before</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the text. That’s because a bug was introduced in Java 1.1<A NAME="Index1262"></A>,
which is shown in the following code:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: IOBug.java</font>
<font color="#009900">// Java 1.1 (and higher?) IO Bug</font>
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> IOBug {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args)
<font color="#0000ff">throws</font> Exception {
DataOutputStream out =
<font color="#0000ff">new</font> DataOutputStream(
<font color="#0000ff">new</font> BufferedOutputStream(
<font color="#0000ff">new</font> FileOutputStream("Data.txt")));
out.writeDouble(3.14159);
out.writeBytes("That was the value of pi\n");
out.writeBytes("This is pi/2:\n");
out.writeDouble(3.14159/2);
out.close();
DataInputStream in =
<font color="#0000ff">new</font> DataInputStream(
<font color="#0000ff">new</font> BufferedInputStream(
<font color="#0000ff">new</font> FileInputStream("Data.txt")));
BufferedReader inbr =
<font color="#0000ff">new</font> BufferedReader(
<font color="#0000ff">new</font> InputStreamReader(in));
<font color="#009900">// The doubles written BEFORE the line of text</font>
<font color="#009900">// read back correctly:</font>
System.out.println(in.readDouble());
<font color="#009900">// Read the lines of text:</font>
System.out.println(inbr.readLine());
System.out.println(inbr.readLine());
<font color="#009900">// Trying to read the doubles after the line</font>
<font color="#009900">// produces an end-of-file exception:</font>
System.out.println(in.readDouble());
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It
appears that anything you write after a call to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeBytes( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is not recoverable. This is a rather limiting bug, and we can hope that it will
be fixed by the time you read this. You should run the above program to test
it; if you don’t get an exception and the values print correctly then
you’re out of the woods.
</FONT><a name="_Toc408018633"></a><P></DIV>
<A NAME="Heading338"></A><H3 ALIGN=LEFT>
Redirecting
standard IO
<P><A NAME="Index1263"></A><A NAME="Index1264"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Java
1.1<A NAME="Index1265"></A>
has added methods in class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>System</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that allow you to redirect the standard input, output, and error IO streams
using simple static method calls:
</FONT><P></DIV><DIV ALIGN=LEFT><A NAME="Index1266"></A><A NAME="Index1267"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>setIn(InputStream)
</B></FONT><P><A NAME="Index1268"></A><A NAME="Index1269"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>setOut(PrintStream)</B></FONT><P><A NAME="Index1270"></A><A NAME="Index1271"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>setErr(PrintStream)
</B></FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Redirecting
output is especially useful if you suddenly start creating a large amount of
output on your screen and it’s scrolling past faster than you can read
it. Redirecting input is valuable for a command-line program in which you want
to test a particular user-input sequence repeatedly. Here’s a simple
example that shows the use of these methods:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Redirecting.java</font>
<font color="#009900">// Demonstrates the use of redirection for </font>
<font color="#009900">// standard IO in Java 1.1</font>
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">class</font> Redirecting {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#0000ff">try</font> {
BufferedInputStream in =
<font color="#0000ff">new</font> BufferedInputStream(
<font color="#0000ff">new</font> FileInputStream(
"Redirecting.java"));
<font color="#009900">// Produces deprecation message:</font>
PrintStream out =
<font color="#0000ff">new</font> PrintStream(
<font color="#0000ff">new</font> BufferedOutputStream(
<font color="#0000ff">new</font> FileOutputStream("test.out")));
System.setIn(in);
System.setOut(out);
System.setErr(out);
BufferedReader br =
<font color="#0000ff">new</font> BufferedReader(
<font color="#0000ff">new</font> InputStreamReader(System.in));
String s;
<font color="#0000ff">while</font>((s = br.readLine()) != <font color="#0000ff">null</font>)
System.out.println(s);
out.close(); <font color="#009900">// Remember this!</font>
} <font color="#0000ff">catch</font>(IOException e) {
e.printStackTrace();
}
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
program attaches standard input to a file, and redirects standard output and
standard error to another file.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is another example in which a deprecation message is inevitable. The message
you can get when compiling with the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-deprecation
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">flag
is:
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>Note:
The constructor java.io.PrintStream(java.io.OutputStream)
</I></FONT><P><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>has
been deprecated.
</I></FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">However,
both
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>System.setOut( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>System.setErr( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
require a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PrintStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object as an argument, so you are forced to call the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PrintStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor. You might wonder, if Java 1.1<A NAME="Index1272"></A>
deprecates the entire
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PrintStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class by deprecating the constructor, why the library designers, at the same
time as they added this deprecation, also add new methods to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>System</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that required a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PrintStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
rather than a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PrintWriter,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
which is the new and preferred replacement. It’s a mystery.
</FONT><a name="_Toc408018634"></a><P></DIV>
<HR><DIV ALIGN=LEFT><A NAME="fn48" HREF="#fnB48">[48]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
Perhaps by the time you read this, the bug will be fixed.
</FONT><P></DIV>
<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0113.html">Prev</a> | <a href="tij0115.html">Next</a>
</div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -