2011-04-15 30 views
5

我在Java中是一個新手,我試圖對文件執行MAC計算。 現在由於文件的大小在運行時不知道,所以我不能將所有文件加載到內存中。所以我編寫了代碼,以便能夠讀取位(本例中爲4k)。 我遇到的問題是我試圖將整個文件加載到內存中,以查看兩種方法是否產生相同的散列。但是他們似乎產生不同的散列Java將文件讀入內存以及如何不炸掉內存

這裏是由位碼位:

FileInputStream fis = new FileInputStream("sbs.dat"); 
byte[] file = new byte[4096]; 
m = Mac.getInstance("HmacSHA1"); 
int i=fis.read(file); 
m.init(key); 
while (i != -1) 
{ 
    m.update(file); 
    i=fis.read(file); 
} 
mac = m.doFinal(); 

而這裏的一次性辦法:

File f = new File("sbs.dat"); 
long size = f.length(); 
byte[] file = new byte[(int) size]; 
fis.read(file); 
m = Mac.getInstance("HmacSHA1"); 
m.init(key); 
m.update(file); 
mac = m.doFinal(); 

難道他們不應該都產生相同的散列?

然而,這個問題是更通用的。第一代碼是將文件加載到內存中的正確方式,並在while循環中執行任何我們想要執行的操作? (套接字發送,密碼文件等)。 這個問題很有用,因爲我看過的每個教程都只是一次加載所有內容...

更新:工作:-D。此方法是否可以正確地通過套接字發送文件?

回答

4

read函數不一定會填滿整個數組。所以,你需要檢查從read函數返回了多少字節,並且只使用緩衝區的很多字節。

5

不可以。您不能保證在fis.read(file)將讀取file.length字節。這就是爲什麼read()返回一個int來告訴你它實際讀取了多少字節。

而應該這樣做:

m.init(key); 
int i=fis.read(file); 

while (i != -1) 
{ 
    m.update(file, 0, i); 
    i=fis.read(file); 
} 

趁着Mac.update(byte[] data, int offset, int len)方法,可以讓你在字節指定實際數據的長度[]數組。

+0

衛生署。我覺得自己像一個白癡,我完全忘記了在Mac課程中有3種更新方法。然而,我仍然會在一些簡單的事情上浪費時間。要嘗試一下,但聽起來不錯。 – ptguy 2011-04-15 20:07:16

1

就像Jason LeBrun所說 - 讀取方法不會總是讀取指定的字節數。例如:如果文件不包含4096字節的倍數,您認爲會發生什麼?

我會去這樣的事情:

 FileInputStream fis = new FileInputStream(filename); 
     byte[] buffer = new byte[buffersize]; 
     Mac m = Mac.getInstance("HmacSHA1"); 
     m.init(key); 

     int n; 
     while ((n = fis.read(buffer)) != -1) 
     { 
      m.update(buffer, 0, n); 
     } 
     byte[] mac = m.doFinal(); 
相關問題