Dennis Grinch Dennis Grinch - 3 months ago 7
Java Question

How to 'clean' InputStream without closing it?

Client code snippet. Basically it reads from standard input and sends message to the server.

public static void main(String[] args) {

try (Socket socket = new Socket("localhost", 1200)) {
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.US_ASCII);

Scanner scanner = new Scanner(System.in);
for (String msg = scanner.nextLine(); !msg.equals("end"); msg = scanner.nextLine()) {
writer.write(msg + "\n");
writer.flush();
}

} catch (IOException e) {
e.printStackTrace();
}
}


Server code snippet. Prints a message from stream.

public void run() {

try (InputStreamReader reader = new InputStreamReader(this.socket.getInputStream(), StandardCharsets
.US_ASCII)) {

StringBuilder builder = new StringBuilder();

for (int c = reader.read(); c != -1; c = reader.read()) {

builder.append((char) c);
if ((char) c == '\n')
System.out.print(builder);
}

} catch (IOException e) {
e.printStackTrace();
}
}


Input from client:

Text1
Text2


Server output:

Text1
Text1
Text2


The problem I am facing that server prints not just received message but also all messages before it.

Question: How can I reset 'clean'
InputStream
without closing it. And if that is impossible what is preferred solution?

Answer

You don't need to 'clean' the stream--you just need to reset the buffer after every line. Try something like the following using StringBuilder.setLength:

if (c == '\n') {
  System.out.print(builder.toString());
  builder.setLength(0);
}

On the other hand, I'd strongly encourage not manually reading lines like that. Consider using a Scanner like you do in the client code or alternatively a BufferedReader.

try (final BufferedReader reader
         = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.US_ASCII))) {
  for (String line = reader.readLine(); line != null; line = reader.readLine()) {
    System.out.println(line);
  }
} catch (final IOException ex) {
  ex.printStackTrace();
}