2013-06-20 65 views
3

我注意到當我在文件上使用readFully()而不是讀取(byte [])時,處理時間大大減少。然而,讀到富利可能是一把雙刃劍。如果我偶然試圖讀取一個巨大的,多GB的文件,它可能會窒息?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這種風險?或者...是最好的選擇(在無法使用數據大小的情況下)始終控制讀入的字節數並使用循環直到讀取所有字節爲止? (想想吧,由於MessageDigest API一次接受完整的字節數組,我不確定如何獲得校驗和而不是立即填充所有數據,但我想這是另一個問題爲另一個線程

+1

您正在使用的'update()'方法不需要所有的數據。您可以在每個摘要中多次調用它。 – erickson

回答

4

你應該只是分配一個體面大小的緩衝區(也許65536字節),並做一個循環,你一次讀64kb,使用「complete.update()」追加到沼氣池內循環,注意最後一個塊,所以你只處理讀取的字節數(可能少於64kb)

1

如果文件是多個千兆字節,但是分配該字節緩衝區,readFully()不會窒息。你會得到一個out-of-m emory異常,然後才能調用readFully()。

您需要使用反覆更新文件塊的散列方法,而不是一次全部更新整個文件。

2

無論您使用readFully()還是不使用,讀取文件所需的時間都會很長。

您是否真的可以分配千兆字節大小的字節數組是另一個問題。下載文件時根本不需要使用readFully()。它用於有線協議,比如說接下來的12個字節是一個標識符,後面跟着另外60個字節的地址信息,您不希望必須繼續寫循環。