2010-06-20 65 views
2

我已經編寫了使用InputStream和FileOutputStream自動下載一批文件的代碼。 的代碼非常簡單:Java下載文件有時會導致CRC

is = urlConn.getInputStream(); 
fos = new FileOutputStream(outputFile); 

eventBus.fireEvent(this, new DownloadStartedEvent(item)); 

int read; 
byte[] buffer = new byte[2048]; 
while ((read = is.read(buffer)) != -1) { 
    fos.write(buffer, 0, read); 
} 

eventBus.fireEvent(this, new DownloadCompletedEvent(item)); 

乍一看,這個作品非常好,但文件會下載沒有任何問題, 偶爾試圖提取一批下載的RAR文件,提取失敗的一個rar部件有CRC錯誤。由於這種情況已經發生了幾次,儘管並不一致,但我開始懷疑這段代碼中的某些內容是不正確/最優的。 這將是讓你知道,有4個下載同時使用JDK FixedThreadPool機制執行:

execService.execute(new Runnable() { 

       @Override 
       public void run() { 
        if (item.getState().equals(DownloadCandidateState.WAITING)) { 
         Downloader downloader = new Downloader(eventBus); 
         downloader.download(item, item.getName()); 
        } 
       } 
}); 

但由於每次下載線程使用下載類的新實例,我相信這個問題是不是副作用併發性? 任何想法,如果偶爾的CRC錯誤與代碼或與其他事情有關?

UPDATE

我可以確認的是有問題的文件的文件大小是正確的。 我也對自動下載的文件和手動下載的文件做了diff(在linux上)。 的文件大小是完全相同的兩個文件,但是,DIFF表示,二進制內容的2個文件之間有所不同:

二進制文件file.rar和文件(2).rar程序不同

UPDATE 2

我用一個可視化的二進制比較工具,可以看到一個128字節的序列是不同的,在文件中間的某個地方。我不明白這是怎麼發生的,因爲下載的文件不會改變,而且它正在使用輸入流讀取每個字節的字節。有任何想法嗎??

+0

你能否批准遠程文件沒有損壞?也許這不是你的下載,而是文件。 – 2010-06-20 19:23:15

+1

你可能需要關閉輸入流 – 2010-06-20 19:29:24

+0

@PartlyCLoudy:是當我手動下載特定文件時,它是正確的 @seanizer:輸入流正在finally塊中關閉,但我把這部分留給了爲了簡潔 – nkr1pt 2010-06-20 19:36:06

回答

0

問題似乎是我的網卡的Linux atheros驅動程序。

0

我將開始通過刷新(或關閉)FileOutputStream中

+0

在finally塊中,輸入流和輸出流都被關閉,按順序 – nkr1pt 2010-06-20 19:54:27

+0

在開始事件之前是否關閉它? – dty 2010-06-21 05:53:10

+0

是在事件被觸發之前 – nkr1pt 2010-06-21 19:05:05

1

您應該運行差異(UNIX工具)比較原始,結果發現什麼實際上已經改變了。你可能馬上看到一個圖案。

+0

我做了一個有問題情況的差異。 自動下載的文件和手動下載文件的大小是一樣的,但是,差異表示二進制內容不一樣: 二進制文件file.rar和文件(2).rar不同 – nkr1pt 2010-06-21 09:43:54

+0

時間去spelunking看看二元差異是什麼.. – 2010-06-21 12:57:57

+0

我更爲困惑的事實,即爲什麼有甚至可能的差異? – nkr1pt 2010-06-21 13:03:48

0

只要關閉了所有內容,並且不會拋出異常,您的代碼就是正確的。問題在別處,可能在原始文件中。