Dennis Grinch Dennis Grinch - 6 months ago 16
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();
}