Rvdrichard
Rvdrichard

Reputation: 335

How to read same inputstream twice without both inputstreams stopping from working

I am trying to create a small application that can send logs with text over a socket. As the socket is accepted the inputstream of that socket will be stored in a HashMap like this.

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

after that I will create a new JFrame for that current inputstream

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();
}

Then I use the inputstream from the list to receive the data and write it on the 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();
        } 
    }
}

This works for receiving the data on 1 JFrame, but once I open 2 JFrames(meaning opening the same inputstream twice) then none of the inputstreams work anymore. I was expecting atleast 1 inputstream would still work.

Upvotes: 0

Views: 618

Answers (1)

Ted Hopp
Ted Hopp

Reputation: 234795

It sounds like you are trying to display the data from an input stream in two distinct views. You can't really read a plain InputStream twice; instead, you need some kind of buffering. So rather than trying to read it twice, I suggest modifying your code in one of two ways, both of which involve using only a single read loop for each stream:

  1. Modify your read loop to update an internal buffer instead of calling logarea.setText(logarea.getText() + addtext);. Whenever the read loop updates the buffer, any interested views should be notified (via some sort of observer pattern that you implement) that the contents have changed.

  2. Modify the read loop to update all interested views instead of having a separate read loop for each JFrame. The read loop would need access to a list of log areas instead of a single logarea. It would loop through the list and update each log area using the same logic you are now using for logarea.

The key thing is to never have two read loops accessing the same input stream.

Upvotes: 1

Related Questions