Как прочитать X байт из потока?

Я хочу прочитать именно n байты из сокета за раз. Как я могу этого достичь?

4 ответов


DataInputStream.readFully()

конечно, он может блокировать в течение произвольно долгого времени...


вы можете создать вспомогательный метод для полного заполнения буфера. Что-то вроде этого:--4-->

public int fillBufferCompletely(InputStream is, byte[] bytes) throws IOException {
    int size = bytes.length;
    int offset = 0;
    while (offset < size) {
        int read = is.read(bytes, offset, size - offset);
        if (read == -1) {
            if ( offset == 0 ) {
                return -1;
            } else {
                return offset;
            }
        } else {
            offset += read;
        }
    }

    return size;
}

тогда вам просто нужно пройти в буфер размера x.

редактировать

Майкл опубликовал ссылку на функцию, которая делает по существу то же самое. Единственное отличие от моего заключается в том, что он имеет возможность возвращать меньше длины буфера, но только при условии окончания потока. DataInputStream.readFully выдаст исключение времени выполнения в этом сценарий.

поэтому я оставлю свой ответ в случае, если пример такого поведения полезен.


DataInputStream.readFully() выбрасывает исключение на EOF, как указывает Марк Петерс. Но есть два других метода, которые этого не делают: Commons IO IOUtils.read () и гуайява байтовым потокам.read (). Они оба пытаются прочитать до N байтов, останавливаясь только на EOF, и возвращают, сколько они на самом деле читают.


Это невозможно. Базовые платформы не могут гарантировать это, так же как и Java. Вы можете попытаться прочитать n байты, но вы всегда должны быть готовы, что вы получите меньше, чем было запрошено.