简体   繁体   中英

Java InputStream read multi part message

I have a task. From InputStream I should receive multi part message. First four bytes it is message length, and other bytes it is message body. At the same time can receive many messages. For example: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

there is

1,2,3,4 - length(in this case 4), 3,4,5,6 - body
7,8,9,10 - length (6), 11,12,13,14,15,16 - body

and so on

Length I compute by this method:

public static int byteArrayToInt(byte[] paRawBytes, int piOffset, boolean pbBigEndian) {

    int iRetVal = -1;

    if(paRawBytes.length < piOffset + 4)
        return iRetVal;

    int iLowest;
    int iLow;
    int iMid;
    int iHigh;

    if(pbBigEndian)
    {
        iLowest = paRawBytes[piOffset + 3];
        iLow    = paRawBytes[piOffset + 2];
        iMid    = paRawBytes[piOffset + 1];
        iHigh   = paRawBytes[piOffset];
    }
    else
    {
        iLowest = paRawBytes[piOffset];
        iLow    = paRawBytes[piOffset + 1];
        iMid    = paRawBytes[piOffset + 2];
        iHigh   = paRawBytes[piOffset + 3];
    }

    // Merge four bytes to form a 32-bit int value.
    iRetVal = (iHigh << 24) | (iMid << 16) | (iLow << 8) | (0xFF & iLowest);

    return iRetVal;
}

And more:

private static void getEventsList(byte[] bytesFromInputStream) {


    int start = 4;

    int end = getLength(bytesFromInputStream) + 4;

    byte[] tmp;

    tmp = Arrays.copyOfRange(bytesFromInputStream, start, end);


    eventsArrayList.add(tmp);

    if (bytesFromInputStream.length > end) {

        byte[] newArray = Arrays.copyOfRange(bytesFromInputStream, end, bytesFromInputStream.length);


        getEventsList(newArray);
    }


}

private static short getLength(byte[] bytes) {
    return ByteUtils.byteArrayToInt(Arrays.copyOfRange(bytes, 0, 4), 0, true);
}

But it is not working and I have not more idea. Help me please

The code you originally provided doesn't quite seem to compile (maybe that was the problem you were having, but you didn't really specify)?

To fix it, I had to get getLength() to return a short by casting the result of byteArrayToInt to short . Or you could just return an int instead. I removed the static reference to ByteUtils because I put all the methods into one class.

I also added an offset of 0 to the call to byteArrayToInt so the method signatures match.

After that, your code seems to work, at least for a few simple cases, eg:

byte[] message = new byte[]{0,0,0,1, 1, 0,0,0,2, 2,3};
getEventsList(message);

produces:

Got a message of length: 1
Content 1
Got a message of length: 2
Content 2
Content 3

(I added some println statements too)

Your byteArrayToInt method does not seem to work correctly for large values (more than 16 bits). There are some example implementations (including some one-liners) in the answers to this question .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM