Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: interspersing bytes and characters

Tags:

java

io

I have a piece of test equipment, from which I can read data using an InputStream, which intersperses bytes and characters (organized into lines), e.g.:

TEST1
TEST2
500
{500 binary bytes follows here}
TEST3
TEST4
600
{600 binary bytes follows here}

I'd like to use BufferedReader so I can read a line at a time, but then switch to InputStream so I can read the binary bytes. But this neither seems to work nor seems like a good idea.

How can I do this? I can't get bytes from a BufferedReader, and if I use a BufferedReader on top of an InputStream, it seems like the BufferedReader "owns" the InputStream.

Edit: the alternative, just using an InputStream everywhere and having to convert bytes->characters and look for newlines, seems like it would definitely work but would also be a real pain.

like image 617
Jason S Avatar asked Nov 22 '25 14:11

Jason S


2 Answers

When using BufferedReader, you can just use String#getBytes() to get the bytes out of a String line. Don't forget to take character encoding into account. I recommend using UTF-8 all the time.

Just for your information: from the other side, if you only have bytes and you want to construct the characters, just use new String(bytes). Also don't forget to take the character encoding into account here.

[Edit] after all, it's a better idea to use BufferedInputStream and construct a byte buffer for a single line (fill until the byte matches the linebreak) and test if the character representation of its start matches with one of the predefined strings.

like image 156
BalusC Avatar answered Nov 24 '25 03:11

BalusC


Instead of using a Reader and InputStream and attempting to switch back and forth between the two, try using a callback interface with one method for binary data and another for character data. e.g.

interface MixedProcessor {
    void processBinaryData(byte[] bytes, int off, int len);
    void processText(String line);
}

Then have another "splitter" class that:

  • Decides which sections of the input are text and which are binary, and passes them to the corresponding processor method
  • Converts bytes to characters when required (with the help of a CharsetDecoder)

The splitter class might look something like this:

class Splitter {
    public Splitter(Charset charset) { /* ... */ }
    public void readFully(InputStream is, MixedProcessor processor) throws IOException  { /* ... */ }
}
like image 38
finnw Avatar answered Nov 24 '25 03:11

finnw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!