Самый быстрый способ чтения относительно огромных байтовых файлов в Java
какой, вероятно, самый быстрый способ чтения относительно огромных файлов с помощью Java I/O-методов? В моем текущем решении используется сохранение BufferedInputStream
в байтовый массив с 1024 байтами, выделенными для него. Каждый буфер хранится в ArrayList
для последующего использования. Весь процесс вызывается через отдельный поток (callable-interface).
Не очень быстро, хотя.
ArrayList<byte[]> outputArr = new ArrayList<byte[]>();
try {
BufferedInputStream reader = new BufferedInputStream(new FileInputStream (dir+filename));
byte[] buffer = new byte[LIMIT]; // == 1024
int i = 0;
while (reader.available() != 0) {
reader.read(buffer);
i++;
if (i <= LIMIT){
outputArr.add(buffer);
i = 0;
buffer = null;
buffer = new byte[LIMIT];
}
else continue;
}
System.out.println("FileReader-Elements: "+outputArr.size()+" w. "+buffer.length+" byte each.");
Ответы
Ответ 1
Я бы использовал файл с отображением памяти, который достаточно быстр, чтобы делать в том же потоке.
final FileChannel channel = new FileInputStream(fileName).getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
// when finished
channel.close();
Предполагается, что файл меньше 2 ГБ и займет 10 миллисекунд или меньше.
Ответ 2
Не используйте available()
: он не является надежным. И не игнорируйте результат метода read()
: он сообщает вам, сколько байтов было действительно прочитано. И если вы хотите прочитать все в памяти, используйте ByteArrayOutputStream вместо использования List<byte[]>
:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read;
while ((read = reader.read(buffer)) >= 0) {
baos.write(buffer, 0, read);
}
byte[] everything = baos.toByteArray();
Я думаю, что 1024 немного меньше размера буфера. Я бы использовал более крупный буфер (что-то вроде 16 КБ или 32 КБ)
Обратите внимание, что у Apache commons IO и Guava есть утилиты, которые делают это для вас и уже оптимизированы.
Ответ 3
Посмотрите API-интерфейс Java NIO (Non-Blocking Input/Output). Кроме того, этот вопрос может оказаться полезным.
У меня нет большого опыта работы с IO, но я слышал, что NIO - это гораздо более эффективный способ обработки больших наборов данных.