我有一个客户端 - 服务器应用程序,其中客户端是:
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
的子类从服务器传输数据。怎么了?
答案 0 :(得分:2)
BufferedWriter
将您write
的任何内容存储在缓冲区中。当缓冲区已满或刷新或关闭时,它会将其写入基础流。
您的代码会写入BufferedWriter
。它没有足够的写入来填充缓冲区,它永远不会刷新或关闭BufferedWriter
,因此BufferedWriter
永远不会将缓冲的数据写入基础流(PrintWriter
)
然后在将任何内容写入out
之前关闭out
。
如果您在第一个代码段中将out.close()
更改为writer.close()
,则可以使用。
这是关闭流的重要原因之一。如果您关闭writer
,它将刷新缓冲区并关闭PrintWriter
(将关闭out
)。请注意,关闭流会将其刷新 - 您不需要单独调用flush
。
我不知道为什么你的第二个代码片段可行。我最好的猜测是,这不是你尝试的确切代码。