0

Below is a snap of my byte stream, first 4 bytes is magic number, next Two bytes are the length of the payload, rest is payload.

How can i read this byte Stream? Encoding is "UTF-16BE"

01:0c:00:00:01:08:00:2f:00:75:00:74:00:69:00:6c:00:69:00:74:00:69:00:65:00:73:00:2f:00:65:00:6c:00:65:00:63:00:74:00:72:00:69:00:63:00:69:00:74:00:79:00:2f:00:7a:00:5f:00:37:00:30:00:62:00:33:00:64:00:35:00:31...More bytes
Sam
  • 6,215
  • 9
  • 71
  • 90
  • I answered this question for you in your [previous post](http://stackoverflow.com/a/35952311/207421), and provided a better solution to that than the one you accepted too. – user207421 Mar 13 '16 at 00:27

1 Answers1

-1

I would go like this:

1) have a method to read a preset amount of bytes from the stream:

private byte[] read(int size) throws IOException {
    byte[] result=new byte[size];
    for (int index=0;index<size;index++) {
        result[index]=in.readByte();
    }
    return result;
}

2) you will need a method to reconstruct the 2 bytes of length marker - I assume here a PC byte order, i.e. LSB - MSB:

private int byteArrayToWord(byte[] value) {
    int ret = ((value[0] & 0xFF) ) | ((value[1] & 0xFF) << 8);

    return ret;
}

3) then read your stuff as:

byte[] magic=read(4);
int len=byteArrayToWord(read(2));

String response=new String(read(len),StandardCharsets.UTF_16); // check the actual charset

Note the string constructor, which allows you to create a string from a byte array using the given encoding. This is the only really tricky part I guess :)

Gee Bee
  • 1,794
  • 15
  • 17
  • All redundant. `DataInputStream` already does all this. – user207421 Mar 13 '16 at 00:27
  • @EJP, I don't think so. DataInputStream does not let you handle different byte ordering of word and int values, and DataInputStream does not let you read in String in an arbitrary encoding. – Gee Bee Mar 13 '16 at 00:49
  • See the duplicate. The OP is using big-endian, as he should, that being the standard over networks, and what `DataInputtStream` implements. – user207421 Mar 13 '16 at 01:00
  • Well, should, and standards are elastic. The OP did not tell anything about the byte ordering of the magic number, neither anything about the byte ordering of the length flag - I assumed it is in PC order. There are may cases when the byte ordering is not in our control. For example, assume an embedded 8 bit processor sends out something to the network. The byte ordering is totally arbitrary, as it sees it in bytes anyways. I find that relying on implicit conversions (such as DataInputStream readInt expects a particular byte order) can make surprises. – Gee Bee Mar 13 '16 at 01:08
  • For the records, I have just had my own set of surprises a week ago, when solving a very same problem, and running into the very same gotchas. – Gee Bee Mar 13 '16 at 01:09
  • I wish you to comment the code that under particular cases, DataInputStream can make things easier. However, DataInputStream will not read 16 bit utf strings, therefore DataInputStream alone is not providing a solution. Would you consider voting up my answer please? – Gee Bee Mar 13 '16 at 01:12