ByteBuffer и FileChannel считывают только указанное количество байтов

#java #file-io #nio #bytebuffer #filechannel

#java #file-io #nio #байтбуфер #filechannel

Вопрос:

У меня ситуация, когда я продолжаю читать с байтбуфером, как показано ниже.

  ByteBuffer buffer = MappedByteBuffer.allocateDirect(Constants.BUFFER_SIZE);
  

Но когда чтение достигает границы (когда оставшиеся для чтения байты меньше, чем BUFFER_SIZE), мне нужно прочитать только boundaryLimit - FileChannel's current position .

Означает, что граничный предел равен x, а текущие позиции — y, тогда мне нужно читать байты из y till x , а не за его пределами.

Как мне этого добиться?

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

Комментарии:

1. Что вы подразумеваете под » когда чтение достигает границы «?

2. Существует ограничение, до которого должно продолжаться только чтение. Байты после этого не должны быть прочитаны. Этот предел является границей. Обновленный вопрос

Ответ №1:

Использование MappedByteBuffer здесь вводит в заблуждение. Вы должны использовать

 ByteBuffer buffer = ByteBuffer.allocateDirect(Constants.BUFFER_SIZE);
  

Если вы прочитали меньше полного количества байтов, это не проблема

 channel.read(buffer);
buffer.flip();
// Will be between 0 and Constants.BUFFER_SIZE
int sizeInBuffer = buffer.remaining(); 
  

РЕДАКТИРОВАТЬ: для чтения из случайного местоположения в файле.

 RandomAccessFile raf = 
MappedByteBuffer buffer= raf.getChannel()
        .map(FileChannel.MapMode.READ_WRITE, start, length);
  

Комментарии:

1. Это очень большой файл, и мне не нужны данные, превышающие верхний предел. На самом деле цель состоит в том, чтобы прочитать данные из указанной начальной позиции до указанной конечной позиции.

2. Существует гораздо более простое решение, если вы хотите прочитать / записать случайную область файла. Вы можете сделать его READ_ONLY или READ_WRITE.

Ответ №2:

На это нет другого ответа, кроме использования другого API, такого как FileInputStream, RandomAccessFile или MappedByteBuffer . Если вам нужно использовать ByteBuffer, вам просто нужно будет самостоятельно обнаружить перечитывание после того, как это произойдет, и соответствующим образом компенсировать.