Search code examples
javasocketsbufferedreaderbufferedinputstream

can't work with BufferedInputStream and BufferedReader together


I'm trying to read first line from socket stream with BufferedReader from BufferedInputStream, it reads the first line(1), this is size of some contents(2) in this content i have the size of another content(3)

  1. Reads correctly... ( with BufferedReader, _bin.readLine() )
  2. Reads correctly too... ( with _in.read(byte[] b) )
  3. Won't read, seems there's more content than my size read in (2)

I think problem is that I'm trying to read using BufferedReader and then BufferedInputStream... can anyone help me ?

public HashMap<String, byte[]> readHead() throws IOException {
    JSONObject json;
    try {
        HashMap<String, byte[]> map = new HashMap<>();
        System.out.println("reading header");
        int headersize = Integer.parseInt(_bin.readLine());
        byte[] parsable = new byte[headersize];
        _in.read(parsable);
        json = new JSONObject(new String(parsable));
        map.put("id", lTob(json.getLong(SagConstants.KEY_ID)));
        map.put("length", iTob(json.getInt(SagConstants.KEY_SIZE)));
        map.put("type", new byte[]{(byte)json.getInt(SagConstants.KEY_TYPE)});
        return map;
    } catch(SocketException | JSONException e) {
        _exception = e.getMessage();
        _error_code = SagConstants.ERROR_OCCOURED_EXCEPTION;
        return null;
    }
}

sorry for bad english and for bad explanation, i tried to explain my problem, hope you understand

file format is so:

size1
{json, length is given size1, there is size2 given}
{second json, length is size2}

_in is BufferedInputStream();
_bin is BufferedReader(_in);

with _bin, i read first line (size1) and convert to integer
with _in, i read next data, where is size2 and length of this data is size1
then im trying to read the last data, its size is size2
something like this:

byte[] b = new byte[secondSize];
_in.read(b);

and nothing happens here, program is paused...


Solution

  • You create one BufferedReader _bin and BufferedInputStream _in and read a file both of them, but their cursor position is different so second read start from beginning because you use 2 object to read it. You should read size1 with _in too.

            int headersize = Integer.parseInt(readLine(_in));
            byte[] parsable = new byte[headersize];
            _in.read(parsable);
    

    Use below readLine to read all data with BufferedInputStream.

        private final static byte NL = 10;// new line
        private final static byte EOF = -1;// end of file
        private final static byte EOL = 0;// end of line
    
    private static String readLine(BufferedInputStream reader,
                String accumulator) throws IOException {
            byte[] container = new byte[1];
            reader.read(container);
            byte byteRead = container[0];
            if (byteRead == NL || byteRead == EOL || byteRead == EOF) {
                return accumulator;
            }
            String input = "";
            input = new String(container, 0, 1);
            accumulator = accumulator + input;
            return readLine(reader, accumulator);
        }