为什么我们必须使用精确的DataOutputStream来传输文本数据?

时间:2014-11-10 06:04:40

标签: java outputstream

我有一个客户端 - 服务器应用程序,其中客户端是:

public static void main(String args[]) throws Exception{
        Socket s = new Socket("localhost", 12345);
        BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
        System.out.println(r.readLine());
        s.close();
    }

和服务器:

public static void main(String args[]) throws Exception{
    @SuppressWarnings("resource")
    ServerSocket server = new ServerSocket(12345);
    Socket client = server.accept();
    OutputStream out = client.getOutputStream();
    //DataOutputStream dout = new DataOutputStream(out);
    BufferedWriter writer = new BufferedWriter(new PrintWriter(out));
    writer.write("String on client's behalf"); //Prints null on the client side. Why?
    out.flush();
    out.close();
    client.close();
}

但如果我们写下以下内容:

public static void main(String args[]) throws Exception{
    @SuppressWarnings("resource")
    ServerSocket server = new ServerSocket(12345);
    Socket client = server.accept();
    OutputStream out = client.getOutputStream();
    DataOutputStream dout = new DataOutputStream(out);
    BufferedWriter writer = new BufferedWriter(new PrintWriter(dout));
    writer.write("String on client's behalf"); //Prints exact what I expected.
    dout.flush();
    dout.close();
    client.close();
}

我无法理解这种差异。 javadoc所说的是

  

这个抽象类是表示一个的所有类的超类   输出字节流。输出流接受输出字节和   把它们送到水槽。

好吧,我刚刚使用abstract class的子类从服务器传输数据。怎么了?

1 个答案:

答案 0 :(得分:2)

BufferedWriter将您write的任何内容存储在缓冲区中。当缓冲区已满或刷新或关闭时,它会将其写入基础流。

您的代码会写入BufferedWriter。它没有足够的写入来填充缓冲区,它永远不会刷新或关闭BufferedWriter,因此BufferedWriter永远不会将缓冲的数据写入基础流(PrintWriter

然后在将任何内容写入out之前关闭out

如果您在第一个代码段中将out.close()更改为writer.close(),则可以使用。

这是关闭流的重要原因之一。如果您关闭writer,它将刷新缓冲区并关闭PrintWriter(将关闭out)。请注意,关闭流会将其刷新 - 您不需要单独调用flush

我不知道为什么你的第二个代码片段可行。我最好的猜测是,这不是你尝试的确切代码。