Как я могу прочитать х байтов из потока? - PullRequest
10 голосов
/ 04 ноября 2011

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

Ответы [ 4 ]

9 голосов
/ 04 ноября 2011

DataInputStream.readFully()

Конечно, он может блокироваться на сколь угодно долго ...

3 голосов
/ 04 ноября 2011

Вы можете создать вспомогательный метод для полного заполнения буфера. Примерно так:

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 выдаст исключение времени выполнения в этом сценарии.

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

2 голосов
/ 30 апреля 2013

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

1 голос
/ 04 ноября 2011

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

...