-1

Environment: input file redirection used while running the program, IDE: Eclipse.

I'm reading packets from System.in (since input redirection is used), and counting the number of packets. I get different counts(all wrong) each time I run the program for the same input. Also, I get the correct count when I display a lot of things on the console.

int packetNumber = 0;
while(System.in.available()>0)
{
    System.out.println("\n" + packetNumber + ": ");
    int numberOfBytes = System.in.read();
    byte[] buffer = new byte[numberOfBytes];
    System.in.read(buffer, 0, numberOfBytes);
    packetNumber++;
}
System.out.println("Number of packets = " + packetNumber);

Working fine with the System.out.println(), but acting weird without it

Thanks in advance.

1 Answers1

0

read(byte[] b, int off, int len) is not required to fill the buffer:

Reads up to len bytes of data from the input stream into an array of bytes. An attempt is made to read as many as len bytes, but a smaller number may be read. The number of bytes actually read is returned as an integer.

That is because of buffering, and the performance difference of the program sending data and this program receiving data, which affect how many bytes are accumulated in the buffer on next call to read().

Assuming that each call to read() returns a single "packet" is definitely wrong.

If you capture the return value as bytesRead and sum those, you should always get the same total.

byte[] buffer = new byte[numberOfBytes];
int totalBytes = 0;
int bytesRead;
while ((bytesRead = System.in.read(buffer)) != -1) {
    totalBytes += bytesRead;
}
System.out.println("Received " + totalBytes + " bytes");
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • numberOfBytes in my code (edited) is calculated dynamically from the input stream and then I've to read numberOfBytes bytes into 'buffer'. I understand that read(byte[] buffer, int off. int len) reads up to len bytes, but how can I ensure that all len bytes are read? – Rohit Nair Oct 07 '16 at 05:18
  • Keep reading until you have all the bytes. Also, be aware that the no-arg `read()` returns a single byte, but as an `int` (0-255), or -1 for EOF. Don't be mislead by the `int` return type to think you're reading a full 4-byte integer value. – Andreas Oct 07 '16 at 07:15
  • reading byte by byte as int and then casting into byte is a solution, but was trying to find a more efficient solution for(int i = 0; i < remainingBytes; i++) buffer[i] = (byte) System.in.read(); – Rohit Nair Oct 07 '16 at 07:32