我有一个客户端-服务器应用程序,其中客户端是:
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说是
This abstract class is the superclass of all classes representing an output stream of bytes. An output stream accepts output bytes and sends them to some sink.
嗯,我只是使用了抽象类
的子类来从服务器传输数据。怎么了?
最佳答案
一个BufferedWriter
存储您的任何东西write
到缓冲区中。当缓冲区已满、刷新或关闭时,它将其写入底层流。
您的代码写入 BufferedWriter
。它写入的内容不足以填充缓冲区,并且它永远不会刷新或关闭 BufferedWriter
,所以BufferedWriter
从不将缓冲数据写入底层流( PrintWriter
)。
然后你关闭out
,在将任何内容写入 out
之前.
如果你改变out.close()
至writer.close()
在您的第一个代码片段中,它可以工作。
这是关闭流很重要的原因之一。如果关闭writer
,它将刷新缓冲区并关闭 PrintWriter
(这将关闭 out
)。请注意,关闭流会刷新它 - 您不需要调用 flush
分别。
我不知道为什么你的第二个代码片段会起作用。我最好的猜测是,这不是您尝试过的确切代码。
关于java - 为什么我们必须使用精确的DataOutputStream来传输文本数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26837740/