如何在两个输入流停止工作的情况下两次读取相同的输入流

时间:2017-04-16 12:25:49

标签: java sockets inputstream datainputstream

我正在尝试创建一个可以通过套接字发送带有文本的日志的小应用程序。当接受套接字时,该套接字的输入流将存储在这样的HashMap中。

private HashMap<Integer,InputStream> allinputsstreams = new 
HashMap<Integer,InputStream>();

之后我将为当前输入流创建一个新的JFrame

public LogListener(int socketid, SocketListener socketlistener, Gui gui) {
    this.socketid = socketid;
    this.gui = gui;
    this.inputstream = socketlistener.getClient(socketid);
    JFrame frame = new JFrame("Log listener");
    frame.setLocationRelativeTo(null);
    frame.setPreferredSize(new Dimension(framewidth,frameheight));
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    logarea = new JTextArea();
    frame.add(logarea);
    frame.pack();
    frame.setVisible(true);
    frame.addWindowListener(this);
    listenthread = new Thread(this);
    listenthread.start();
}

然后我使用列表中的输入流来接收数据并将其写在JFrame

public void run() {
    input = new DataInputStream(inputstream);
    while(!formclosed) {
        try {
            String addtext = input.readUTF();
            addtext = formatText(addtext);
            logarea.setText(logarea.getText() + addtext);
        } catch (EOFException e) {
            System.out.println("Looks like the client has been closed.");
            return;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

这适用于接收1 JFrame上的数据,但是一旦我打开2个JFrame(意味着打开两次相同的输入流),那么任何输入流都不再有效。我期待至少1个输入流仍然可以工作。

1 个答案:

答案 0 :(得分:1)

听起来您正试图在两个不同的视图中显示输入流中的数据。你不能真正阅读普通的InputStream两次;相反,你需要某种缓冲。因此,我建议不要尝试两次读取,而是以两种方式之一修改代码,这两种方式都只涉及为每个流使用一个读取循环:

  1. 修改您的读取循环以更新内部缓冲区,而不是调用logarea.setText(logarea.getText() + addtext);。每当读取循环更新缓冲区时,应通知任何感兴趣的视图(通过您实现的某种观察者模式)内容已更改。

  2. 修改读取循环以更新所有感兴趣的视图,而不是为每个JFrame设置单独的读取循环。读取循环需要访问日志区域列表而不是单个logarea。它将遍历列表并使用您现在用于logarea的相同逻辑更新每个日志区域。

  3. 关键是永远不要有两个读取循环访问相同的输入流。