Input Stream only returning 1 byte

1.9k Views Asked by At

I am using java comm library to try accomplish a simple read/write to a serial port. I am able to successfully write to the port, and catch the return input from the input stream, but when I read from the input stream I am only able to read 1 byte (when I know there should be 11 returned)

I can write to the port successfully using Putty and am receiving the correct return String there. I am pretty new to Java, buffers and serial i/o and think maybe there is some obvious syntax or understanding of how data is returned to the InputStream. Could someone help me? Thanks!

    case SerialPortEvent.DATA_AVAILABLE:
        System.out.println("Data available..");
        byte[] readBuffer = new byte[11];
        try {
            System.out.println("We trying here.");
            while (inputStream.available() > 0) {
                int numBytes = inputStream.read(readBuffer, 1, 11);
                System.out.println("Number of bytes read:" + numBytes);

            }

            System.out.println(new String(readBuffer));

        } catch (IOException e) {System.out.println(e);}
        break;
    } 

This code returns the following output:

Data available..
We trying here.
Number of bytes read:1
U
1

There are 1 best solutions below

0
On

As the documentation states

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.

This behavior is perfectly legal. I would also expect that a SerialPortEvent.DATA_AVAILABLE does not guarantee that all data is available. It's potentially just 1 byte and you get that event 11 times.

Things you can try:

1) Keep reading until you have all your bytes. E.g. wrap your InputStream into a DataInputStream and use readFully, that's the simplest way around the behavior of the regular read method. This might fail if the InputStream does not provide any more bytes and signals end of stream.

DataInputStream din = new DataInputStream(in);
byte[] buffer = new byte[11];
din.readFully(buffer);
// either results in an exception or 11 bytes read

2) read them as they come and append them to some buffer. Once you have all of them take the context of the buffer as result.

private StringBuilder readBuffer = new StringBuilder();
public void handleDataAvailable(InputStream in) throws IOException {
    int value;
    // reading just one at a time
    while ((value = in.read()) != -1) {
        readBuffer.append((char) value);
    }
}

Some notes:

inputStream.read(readBuffer, 1, 11)

Indices start at 0 and if you want to read 11 bytes into that buffer you have to specify

inputStream.read(readBuffer, 0, 11)

It would otherwise try to put the 11th byte at the 12th index which will not work.