2016-06-08 2 views
1

Как получить байты файлов в заданном диапазоне? Файл может быть очень большим, поэтому хранить все байты в памяти - это не очень хорошая идея. Могу ли я просто прочитать байт файла байтом? Является ли чтение таким нормальным?Как получить байты файлов в заданном диапазоне?

+2

Посмотрите на «RandomAccessFile». – Berger

+0

@NicolasFilotto, binary – Tony

ответ

1

Я согласен с @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); 
} 
+0

Это выглядит неправильно: в документации указано, что вы не можете получить точное количество байтов, о которых вы просите. Итак ... вы должны сделать свой цикл кода, пока это не так. – GPI

+0

@GPI, можете ли вы предоставить код? – Tony

+0

Вы можете посмотреть исходный код DataInputStream # readFully, который делает это. – GPI

0

Вообще говоря, это редко хорошая идея, чтобы загрузить весь файл в память, если вы не знаете, что он всегда будет быть достаточно маленьким, чтобы вписаться в вашу память, и вы не будете загружать несколько файлов параллельно, иначе вы можете столкнуться с 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)

0

Открыть файл с использованием 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; 
    } 
}