Java – 了解PrintWriter并需要刷新

好的,首先我为所有代码道歉,但我觉得太多的代码比不够好。 我正在制作一个简单的聊天客户端和编剧,特别是我正在努力。 使用代码的方式现在它将与服务器类进行交互,并且非常精细并打印我想要打印的内容。 但是,当我删除’writer.flush();’ 它会停止打印。 凭借我的理解 – 这显然是错误的 – ‘writer.println(outgoing.getText());’ 应该足够了,因为这会发送我试图发送到服务器的文本。 我理解flush会强制写入所有信息,但为什么在我写完我想写的内容时需要这样做?

public class SimpleChatClientA { JTextArea incoming; JTextField outgoing; BufferedReader reader; PrintWriter writer; Socket sock; public void go(){ JFrame frame = new JFrame("Ludicrously Simple Chat Client"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel mainPanel = new JPanel(); incoming = new JTextArea(15,50); incoming.setLineWrap(true); incoming.setWrapStyleWord(true); incoming.setEditable(false); JScrollPane qScroller = new JScrollPane(incoming); qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); outgoing = new JTextField(20); JButton sendButton = new JButton("Send"); sendButton.addActionListener(new SendButtonListener()); mainPanel.add(qScroller); mainPanel.add(outgoing); mainPanel.add(sendButton); setUpNetworking(); Thread readerThread = new Thread(new IncomingReader()); readerThread.start(); frame.getContentPane().add(BorderLayout.CENTER, mainPanel); frame.setSize(400, 500); frame.setVisible(true); }//close go public void setUpNetworking(){ try{ sock = new Socket("127.0.0.1", 5000); InputStreamReader streamReader = new InputStreamReader(sock.getInputStream()); reader = new BufferedReader(streamReader); writer = new PrintWriter(sock.getOutputStream()); System.out.println("network established"); }catch(Exception e){ e.printStackTrace(); } }//close setupnetworking public class SendButtonListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { try{ writer.println(outgoing.getText()); writer.flush(); }catch(Exception ex){ ex.printStackTrace(); } outgoing.setText(""); outgoing.requestFocus(); } }//close sendbuttonlistener inner class public class IncomingReader implements Runnable{ public void run(){ String message; try{ while((message = reader.readLine()) != null){ System.out.println("read " + message); incoming.append(message + "\n"); } }catch(Exception e){ e.printStackTrace(); } } }//close inner class incomingreader public static void main(String[] args){ new SimpleChatClientA().go(); } 

}

在此先感谢,如果有更多信息我可以给我,请让我知道我第一次正确发布到stackoverflow。

仅当启用了autoFlush属性时, PrintWriter类的println()方法才会将数据“提交”到流中。

从Java文档中看这个引用:

如果启用了自动刷新,则只有在调用println,printf或format方法之一时才会执行

链接到Java文档: https : //docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html#PrintWriter( java.io.OutputStream,% 20boolean)

如果需要将消息发送到服务器,则在打开autoflush选项的情况下创建PrintWriter对象。

那么,在创建writer对象的地方,只需执行以下操作:

writer = new PrintWriter(sock.getOutputStream(), true);

应该这样做。 希望能帮助到你!

每次println后不刷新数据效率更高。 如果您正在编写大量数据,则需要缓冲它并发送大块数据,而不是单独发送每一行。 这就是为什么你需要手动刷新流,如果你想确保数据确实发送到另一端。

想象一下,您正在向朋友发送电子邮件,并将每个单词作为自己的电子邮件发送,而不是通过一封电子邮件发送整个文本。 您认为哪个更快? 当然,如果您按照自己的想法发送每个单词,您的朋友将会更快地阅读邮件,但所用的总时间会变得更长。