Будет ли FileChannel.read читать меньше байтов, чем указано, если данных достаточно?
Например, у меня есть файл, содержание которого:
abcdefg
Затем я использую следующий код, чтобы прочитать "Defg".
ByteBuffer bb = ByteBuffer.allocate(4);
int read = channel.read(bb, 3);
assert(read == 4);
Поскольку в файле достаточно данных, могу ли я так предположить? Могу ли я предположить, что метод возвращает число меньше лимита данного буфера, только если в файле недостаточно байтов?
2 ответа
Могу ли я предположить, что метод возвращает число меньше лимита данного буфера, только если в файле недостаточно байтов?
Javadoc говорит:
чтение может не заполнить буфер
и приводит несколько примеров, и
возвращает количество прочитанных байтов, возможно, ноль или -1, если канал достиг конца потока.
Этого недостаточно, чтобы вы могли сделать такое предположение.
На практике вы, скорее всего, всегда получите полный буфер при чтении из файла, по модулю конца файла. И это имеет смысл с точки зрения реализации ОС, учитывая накладные расходы при выполнении системного вызова.
Но я также могу представить себе ситуации, когда возвращение полупустого буфера может иметь смысл. Например, при чтении из локально установленной удаленной файловой системы по медленному сетевому каналу есть некоторое преимущество в возврате частично заполненного буфера, чтобы приложение могло начать обработку данных. Некоторые будущие ОС могут реализовать read
Системный вызов, чтобы сделать это в этом сценарии. Если предположить, что вы всегда получите полный буфер, вы можете удивиться, когда ваше приложение будет запущено на (гипотетической) новой платформе.
Другая проблема заключается в том, что есть несколько видов потоков, где вы определенно получите частично заполненные буферы. Сокетные потоки, каналы и консольные потоки являются очевидными примерами. Если вы закодируете свое приложение в предположении о поведении файлового потока, вы можете получить неприятный сюрприз, когда кто-то запустит его в другом потоке... и не получится.
Нет, в общем, вы не можете предполагать, что число прочитанных байтов будет равно количеству запрошенных байтов, даже если в файле остались байты, которые нужно прочитать.
Если вы читаете из локального файла, есть вероятность, что количество запрошенных байтов будет действительно прочитано, но это никоим образом не гарантировано (и, скорее всего, не будет иметь место, если вы читаете файл по сети).
Смотрите документацию для ReadableByteChannel.read(ByteBuffer)
метод (который применяется для FileChannel.read(ByteBuffer)
также). Предполагая, что канал находится в режиме блокировки, единственной гарантией является то, что будет прочитан хотя бы один байт.