Как получить байты файлов в заданном диапазоне? Файл может быть очень большим, поэтому хранить все байты в памяти - это не очень хорошая идея. Могу ли я просто прочитать байт файла байтом? Является ли чтение таким нормальным?Как получить байты файлов в заданном диапазоне?
ответ
Я согласен с @Berger, вы можете использовать RandomAccessFile в java. Вы можете использовать что-то вроде приведенного ниже кода для случайного чтения файла.
RandomAccessFile f = new RandomAccessFile("FilePath","r");
byte[] buffer = new byte[1024];
f.read(buffer, 10, 100);
Ниже приводится документация для чтения() методом из Java-докторской дис-
/**
* Reads up to <code>len</code> bytes of data from this file into an
* array of bytes. This method blocks until at least one byte of input
* is available.
* <p>
* Although <code>RandomAccessFile</code> is not a subclass of
* <code>InputStream</code>, this method behaves in exactly the
* same way as the {@link InputStream#read(byte[], int, int)} method of
* <code>InputStream</code>.
*
* @param b the buffer into which the data is read.
* @param off the start offset in array <code>b</code>
* at which the data is written.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception IOException If the first byte cannot be read for any reason
* other than end of file, or if the random access file has been closed, or if
* some other I/O error occurs.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
*/
public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}
Это выглядит неправильно: в документации указано, что вы не можете получить точное количество байтов, о которых вы просите. Итак ... вы должны сделать свой цикл кода, пока это не так. – GPI
@GPI, можете ли вы предоставить код? – Tony
Вы можете посмотреть исходный код DataInputStream # readFully, который делает это. – GPI
Вообще говоря, это редко хорошая идея, чтобы загрузить весь файл в память, если вы не знаете, что он всегда будет быть достаточно маленьким, чтобы вписаться в вашу память, и вы не будете загружать несколько файлов параллельно, иначе вы можете столкнуться с OOME
.
Если вы хотите прочитать файл, вы можете прочитать байты по байтам, используя метод read(), но на практике он используется в особых случаях использования, когда вам нужно прочитать несколько байтов, поскольку это не оптимизированный способ прочитайте весь файл.
Общий код в этом случае:
int data;
while ((data = input.read()) != -1) {
// Do something with data
}
Если вы хотите, чтобы прочитать файл быстрее, вы должны использовать метод read(byte[] b), что позволяет повторно использовать массив байтов ранее созданных кодом вызывающего абонента и читать диапазон байтов, как то, что вы хотите сделать.
Общий код в этом случае:
int length;
byte[] data = new byte[someSizeHere];
while ((length = input.read(data)) != -1) {
// Do something with the bytes in data between index 0 and length - 1
}
Если вы хотите, чтобы пропустить несколько байт, прежде чем начать читать диапазон байтов, вы действительно можете использовать RandomAccessFile
и его метод seek(long)
Открыть файл с использованием RandomAccessFile
, найдите начальное смещение, определите длину буфера и полностью прочитайте буфер. Оператор try-with-resources
заботится о закрытии RandomAccessFile
.
public static byte[] readByteRange(String sourceFilePath, long startingOffset, int length) throws IOException
{
try (RandomAccessFile randomAccessFile = new RandomAccessFile(sourceFilePath, "r"))
{
byte[] buffer = new byte[length];
randomAccessFile.seek(startingOffset);
randomAccessFile.readFully(buffer);
return buffer;
}
}
Посмотрите на «RandomAccessFile». – Berger
@NicolasFilotto, binary – Tony