Robby Smet
Robby Smet

Reputation: 4661

Read from inputstream and add to stringbuilder

private void readIncomingMessage() {
    try {
        StringBuilder builder = new StringBuilder();
        InputStream is = socket.getInputStream();
        int length = 1024;
        byte[] array = new byte[length];
        int n = 0;

        while ((n = is.read(array, n, 100)) != -1) {
            builder.append(new String(array));

            if (checkIfComplete(builder.toString())) {
                buildListItems(builder.toString(), null);
                builder = new StringBuilder();
            }
        }

    } catch (IOException e) {
        Log.e("TCPclient", "Something went wrong while reading the socket");
    }
}

Hi,

I want to read the stream per block of 100 bytes, convert those bytes into a string and than see if that strings fits certain conditions.

But when I debug I see that builder has a count of 3072.
And I see a string like (text, , , , , , , , , , text , , , , , , , , , text)
How can I just add the text to the stringbuilder?

thx :)

 private void readIncomingMessage() {
    try {
        StringBuilder builder = new StringBuilder();
        InputStream is = socket.getInputStream();
        int length = 100;
        byte[] array = new byte[length];
        int n = 0;

        while ((n = is.read(array, 0, length)) != -1) {
            builder.append(new String(array, 0, n));

            if (checkIfComplete(builder.toString())) {
                buildListItems(builder.toString(), null);
                builder = new StringBuilder();
            }
        }

    } catch (IOException e) {
        Log.e("TCPclient", "Something went wrong while reading the socket");
    }
}

this solution did the trick for me. any drawbacks with this solution?

Upvotes: 0

Views: 5981

Answers (2)

jtahlborn
jtahlborn

Reputation: 53694

2 problems:

  1. you need to use the 'n' value when converting the bytes to a String. Specifically, use this String constructor String(byte[] bytes, int offset, int length)
  2. when converting bytes to strings on arbitrary boundaries, like you are doing, you have the potential to corrupt multi-byte characters. You'd be better off putting an InputStreamReader on top if the 'is' and reading characters from that.

Upvotes: 2

Jacob is on Codidact
Jacob is on Codidact

Reputation: 3750

For more information read the documentation for read(byte[], int, int), new String(byte[]) and new String(byte[], int, int)

n will hold the number of bytes read in the last read operation - not the total number of bytes read. If you only want to read up to 100 bytes at a time, there is no need for a byte array of size 1024, 100 will do. When you create a String from a byte array, it uses the entire array (even if only half was able to be filled by reading), unless you tell it which parts of the array you want to use. Something like this should work, but there are still improvements you could make:

private void readIncomingMessage() {
  try {
    StringBuilder builder = new StringBuilder();
    InputStream is = socket.getInputStream();
    int length = 100;
    byte[] array = new byte[length];
    int pos = 0;
    int n = 0;

    while (pos != length && ((n = is.read(array, pos, length-pos)) != -1)) {
        builder.append(new String(array, pos, n));
        pos += n;
        if (checkIfComplete(builder.toString())) {
            buildListItems(builder.toString(), null);
            builder = new StringBuilder();
            pos = 0;
        }
    }

} catch (IOException e) {
    Log.e("TCPclient", "Something went wrong while reading the socket");
}

}

Upvotes: 1

Related Questions