2013-06-20 4 views
3

Я заметил, что при использовании readFully() в файле вместо чтения (байт []) время обработки значительно сокращается. Однако мне показалось, что readFully может быть обоюдоострым мечом. Если я случайно попытаюсь прочитать в огромном многогигабайтном файле, это может задохнуться?ReadFully() Возникает риск удушения?

Вот функция, я использую для создания SHA-256 контрольной суммы:

public static byte[] createChecksum(File log, String type) throws Exception { 
    DataInputStream fis = new DataInputStream(new FileInputStream(log)); 
    Long len = log.length(); 
    byte[] buffer = new byte[len.intValue()]; 
    fis.readFully(buffer); // TODO: readFully may come at the risk of 
          // choking on a huge file. 
    fis.close(); 
    MessageDigest complete = MessageDigest.getInstance(type); 
    complete.update(buffer); 
    return complete.digest(); 
} 

Если бы я вместо этого использовать:

DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(log))); 

бы, allieviate этот риск? Или ... лучший вариант (в ситуациях, когда вы не можете использовать размер данных), чтобы всегда контролировать количество прочитанных байтов и использовать цикл до тех пор, пока все байты не будут прочитаны?

(Подумайте об этом, так как API MessageDigest сразу принимает полный массив байтов, я не уверен, как достичь контрольной суммы, не набирая сразу все данные, но я полагаю, что это еще один вопрос для другой нити.

+1

Метод 'update()', который вы используете, не требует всех данных. Вы можете вызывать его несколько раз за дайджест. – erickson

ответ

4

Вы должны просто выделить буфер с приличным размером (возможно, 65536 байтов) и сделать цикл, в котором вы читаете 64 КБ за один раз, используя «complete.update()» для добавления в варочный котел внутри Обратите внимание на последний блок, так что вы обрабатываете только количество прочитанных байтов (возможно, менее 64 КБ).

1

readFully() не будет задыхаться, если файл имеет несколько гигабайт, но выделение этого байтового буфера будет. Вы получите не-м исключение emory, прежде чем вы когда-нибудь дойдете до вызова readFully().

Необходимо повторно использовать метод обновления хэша с фрагментами файла, а не обновлять его сразу всего файла.

2

Чтение файла займет столько же времени, сколько вы используете readFully() или нет.

Если вы действительно можете назначить гигабайтные массивы байтов, это еще один вопрос. При загрузке файлов вообще не нужно использовать readFully(). Он предназначен для использования в проводных протоколах, где говорят, что следующие 12 байтов являются идентификаторами, за которыми следуют еще 60 байтов адресной информации, и вы не хотите, чтобы они продолжали писать циклы.