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

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

{chunk_1_size}
{chunk_1}
{chunk
while(!EOF) {
    /*chunk is an integer i.e. 4 bytes*/
    readChunkSize(); 
    /*according to chunk size read the number of bytes from file*/
    readChunk(chunkSize);   
}
size} {chunk_2} {chunk_3_size} {chunk_3} {chunk_4_size} {chunk_4} {chunk_5_size} {chunk_5} . . {chunk_n_size} {chunk_n}

Файл действительно большой ~ 2 ГБ, а размер блока составляет ~ 20 МБ (это буфер, который я хочу иметь)

Я хотел бы, чтобы буфер прочитал этот файл, чтобы уменьшить количество обращений к реальному жесткому диску.

Но я не уверен, сколько буфера нужно иметь, потому что размер блока может отличаться.

псевдокод того, что я имею в виду:

while(!EOF) {
    /*chunk is an integer i.e. 4 bytes*/
    readChunkSize(); 
    /*according to chunk size read the number of bytes from file*/
    readChunk(chunkSize);   
}

Допустим, у меня случайный размер буфера, тогда я могу заползать в такие ситуации, как:

  1. Первый буфер содержит chunkSize_1 + chunk_1 + partialChunk_2 --- я должен отслеживать остаток, а затем из следующего буфера получить оставшийся фрагмент и объединить его с остатком, чтобы завершить фрагмент
  2. Первый буфер содержит chunkSize_1 + chunk_1 + partialChunkSize_2 (размер фрагмента является целым числом, т.е. 4 байта, поэтому скажем, я получаю только два из них из первого буфера) --- я должен отслеживать partialChunkSize_2, а затем получить оставшиеся байты из следующего буфера для сформировать целое число, которое фактически дает мне следующий размер блока
  3. Буфер может даже не получить по одному целому фрагменту за раз - я должен продолжать нажимать чтение, пока первый фрагмент не будет полностью считан в память

person Nick Div    schedule 09.02.2017    source источник


Ответы (2)


У вас нет особого контроля над количеством обращений к жесткому диску. Между вами и жестким диском есть несколько уровней (ОС, драйвер, аппаратная буферизация), которыми вы не можете управлять.

Установите разумный размер буфера в коде Java (1M) и забудьте о нем до тех пор, пока вы не докажете, что существует проблема производительности, которая напрямую связана с размерами буфера. Другими словами, не попадитесь в ловушку преждевременной оптимизации.

См. Также https://stackoverflow.com/a/385529/18157.

person Jim Garrison    schedule 09.02.2017
comment
Судя по тому, что я тестировал, ~ 20 МБ были очень быстрыми на моей машине и на сервере. Я просто не доволен всеми пластырями, которые у меня есть между двумя последовательными чтениями файла, то есть в буфер. - person Nick Div; 09.02.2017

вам может потребоваться провести некоторый анализ и иметь представление о среднем размере буфера для чтения данных. вы говорите сохранить размер буфера и читать данные до тех пор, пока кусок не будет готов, чтобы иметь какое-то значение полные данные R u копируя файл в какое-то другое место, или вы отправляете эти данные в другое место? для некоторых действий пакеты Java NIO имеют лучшую реализацию, чем чтение данных в буферы jvm. размер буфера должен быть достаточно приличным для чтения максимального количества фрагментов данных.Если планирование хранения данных в памяти, чтение данных с использованием буферов и удержание их в памяти по-прежнему требует затрат памяти, буферы могут быть освобождены разными способами, используя базовые операции сброса. . пожалуйста, также проверьте apache file-utils для чтения / записи данных

person Fryder    schedule 09.02.2017
comment
Я не против использования Java NIO, но я не слишком уверен в них и не могу судить, подходят ли они в данном случае. Я использую этот фрагмент данных для отображения в пользовательском интерфейсе на панели отчетов. - person Nick Div; 09.02.2017
comment
попробуйте рассмотреть решение, в котором вы передаете все данные во внешнее приложение, такое как эластичный поиск, и индексируете их, чтобы отображать в пользовательском интерфейсе, даже распределенные кеши, такие как hazel-cast / redis (очистите данные после завершения), будут содержать много данных. не имеет значения, сколько раз он попадает на жесткий диск (как os с jvm и java-программа), решит, что попаданий нет io.Примечание: - производительность NIO зависит от базовой ОС и операции, которую вы пытаетесь выполнить - person Fryder; 09.02.2017
comment
Я ценю это предложение, но с теми ресурсами, которые у меня есть прямо сейчас, я не могу реально расширить свои варианты реализации. - person Nick Div; 10.02.2017