Java: interleaved bytes and characters

I have a piece of test equipment from which I can read data using InputStreamthat interleaves bytes and characters (organized into strings), for example:

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

I would like to use BufferedReader so that I can read a string at a time, but then switch to InputStream so that I can read binary bytes. But this does not seem to work and does not seem to be a good idea.

How can i do this? I cannot get bytes from BufferedReader, and if I use BufferedReader on top of InputStream, it seems that BufferedReader "owns" InputStream.

Edit: an alternative, just using an InputStream everywhere and forcing byte-> characters to be converted and looking for newlines, it seems like it will definitely work, but it will also be a real pain.

+3
6

BufferedReader String#getBytes(), String. . UTF-8 .

: , , , new String(bytes). .

[Edit] , BufferedInputStream (, ) , .

+1

Reader InputStream , , . .

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

"splitter", :

  • , , .
  • ( CharsetDecoder)

:

class Splitter {
    public Splitter(Charset charset) { /* ... */ }
    public void readFully(InputStream is, MixedProcessor processor) throws IOException  { /* ... */ }
}
+1

, java.nio.ByteBuffer ByteBuffer.asCharBuffer, . , , , , .

0

LineNumberInputStream. , , , .

, InputStream.

, .

0

( ), , ISO-8859-1 (8- ), , , 8- char ISO-8859-1.

InputStream.read(byte [] b) InputStream.read(byte [] b, intss, int len) .

public class OctetCharStream extends InputStream {
    final private InputStream in;
    static final private String charSet = "ISO-8859-1";

    public OctetCharStream(InputStream in)
    {
        this.in=in;
    }

    @Override public int read() throws IOException {
        return this.in.read();
    }

    public String readLine() throws IOException
    {
        StringBuilder sb = new StringBuilder();
        while (true)
        {
            /*
             *  cast from byte to char: 
             *  fine for 8-byte character sets
             *  but not good in general 
             */
            char c = (char) read();
            if (c == '\n')
                break;          
            sb.append(c);
        }
        return sb.toString();
    }
    public String readCharacters(int n) throws IOException
    {
        byte[] b = new byte[n];
        int i = read(b);
        String s = new String(b, 0, i, charSet);
        return s;
    }
}

, InputStreamReader, BufferedReader , InputStreamReader.read() , "" , . InputStreamReader InputStream InputStream, InputStreamReader /, .

0

BufferedReader read(char[] cbuf, int off, int len), , ByteArrayInputStream?

EDIT: why would anyone do this? Please comment. This works great:

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try {
        bos.write("TEST1\n".getBytes());
        bos.write("10\n".getBytes());
        for (int i = 0; i < 10; i++)
            bos.write(i);
        bos.write("TEST2\n".getBytes());
        bos.write("1\n".getBytes());
        bos.write(25);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        BufferedReader br = new BufferedReader(new InputStreamReader(bis));

        while (br.ready()) {
            String s = br.readLine();
            String num = br.readLine();
            int len = Integer.valueOf(num);
            System.out.println(s + ", reading " + len + " bytes");
            char[] cbuf = new char[len];
            br.read(cbuf);
            byte[] bbuf = new byte[len];
            for (int i = 0; i < len; i++)
                bbuf[i] = (byte) cbuf[i];
            for (byte b: bbuf)
                System.out.print(b + " ");
            System.out.println();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

Exit:

TEST1, reading 10 bytes
0 1 2 3 4 5 6 7 8 9 
TEST2, reading 1 bytes
25 
-1
source

Source: https://habr.com/ru/post/1721914/


All Articles