2012-04-03 106 views
2

我嘗試使用下面的代碼複製文件:如何確定緩衝區大小的BufferedOutputStream的write方法

1:

 int data=0; 
     byte[] buffer = new byte[4096]; 
     while((data = bufferedInputStream.read())!=-1){ 
      bufferedOutputStream.write(data); 
     } 

2:

 byte[] buffer = new byte[4096]; 
     while(bufferedInputStream.read(buffer)!=-1){ 
      bufferedOutputStream.write(buffer); 
     } 

實際尺寸文件是3892028字節(在窗口上)。該文件將由用戶thro struts2 fileupload上傳。上傳的文件大小與Windows完全相同。當我嘗試從臨時文件夾中複製上載的文件時,複製的文件大小不一,所用的時間也會有所不同(可以忽略不計)。請找到下面的讀物。

Without using buffer(Code 1) 
Time taken 77 
3892028 
3891200 

Buffer size 1024(Code 2) 
Time taken 17 
3892028 
3891200 

Buffer size 4096(Code 2) 
Time taken 18 
3892028 
3891200 

Buffer size 10240(Code 2) 
Time taken 14 
3892028 
3901440 

Buffer size 102400(Code 2) 
Time taken 9 
3892028 
3993600 

如果我進一步增加緩衝區大小,所花費的時間會增加,同樣可以忽略不計。所以我的問題是,

  1. 爲什麼文件大小改變?
  2. 由於此尺寸變化,是否有任何微妙的後果?
  3. 完成此功能(複製文件)的最佳方法是什麼?

我不知道下面會發生什麼?感謝您的任何建議。 編輯:我有flush()和close()方法調用。 注:我修剪了我的代碼,使其更簡單。

+1

如果你正在讀大量的數據,你不需要使用緩衝流。它們的目的是將小的讀/寫轉化爲大塊的數據。 – 2012-04-03 13:43:21

回答

5
  1. 爲什麼文件大小發生變化?
你忘了`的flush()`(和'close()方法`): bufferedOutputStream.flush()

你也應該通過讀取write的字節數方法:

bufferedOutputStream.write(data, 0, bytesRead); 
  1. 完成此功能(複製文件)的最佳方法是什麼?

無論從 IO。

+0

我在他們的代碼()中有他們。我也會更新我的問題。 – Ahamed 2012-04-03 13:26:19

10

問題是,BufferedInputStream.read(byte[])讀取儘可能多的數據到緩衝區中。所以如果流只包含1個字節,只有字節數組的第一個字節會被填充。但是,BufferedInputStream.write(byte[])全部寫入流中,這意味着它仍將寫入完整的4096個字節,其中包含當前迭代的1個字節和來自先前迭代的4095個剩餘字節。

你需要做的是保存讀取的字節數量,然後寫入相同的數量。

例子:

int lastReadCnt = 0; 
byte[] buffer = new byte[4096]; 
while((lastReadCnt = bufferedInputStream.read(buffer))!=-1){ 
    bufferedOutputStream.write(buffer, 0, lastReadCnt); 
} 

參考文獻:

+0

我不明白爲什麼生成的文件比前三個例子中的原始文件要小。這與代碼是'while(bufferedInputStream.read(buffer)== buffer.length){')的結果是一樣的。 – boumbh 2015-10-15 16:30:37

+1

@boumbh這種現象發生是因爲他沒有刷新BufferedOutputStream。緩衝區的默認大小爲8192字節,並且每次填充時都會自動刷新。並且寫入的最後一批數據沒有填充流的緩衝區,因此它從不刷新到基礎流。另外,在對另一個答案發表評論時,艾哈邁德提到他確實有'沖水'和'關閉'。但是,我猜他從來沒有刷新/關閉BufferedOutputStream,而是直接隱藏底層的。因此緩衝的一個從未被通知,並且永遠不會刷新它的未填充的緩衝區。 – bezmax 2015-10-16 07:36:15