2013-10-03 23 views
0

我通過套接字發送文件,並試圖將它寫入接收器的文件。從InputStream複製到BufferedOutputStream

我見過的例子是做這樣的事情:

int bytesRead = 0; 
while (bytesRead != -1) 
{ 
    bytesRead = networkInputStream.read(buffer, 0, diskBlockSizeEstimate); 
    bufferedOutputStream.write(buffer, 0, bytesRead); 
} 

然而,從http://developer.android.com/reference/java/io/InputStream.html#read%28byte [] %29它會像.read一樣返回-1,當流結束時達到。然後,當使用-1調用.write時,會引發異常。我一定要執行,說的邏輯:「如果(bytesRead == - 1)設置bytesToRead =檔案大小 - totalBytesRead」或這樣的事情:

int fileSize = ... get filesize from sender ...; 
int totalBytesRead = 0; 
int bytesRead = 0; 
while (bytesRead != -1) 
{ 
    bytesRead = networkInputStream.read(buffer, 0, diskBlockSizeEstimate); 
    if(bytesRead == -1) 
    { 
     bufferedOutputStream.write(buffer, 0, fileSize - totalBytesRead); 
     totalBytesRead += fileSize - totalBytesRead; 
    } 
    else 
    { 
     bufferedOutputStream.write(buffer, 0, bytesRead); 
     totalBytesRead += bytesRead; 
    } 
} 

而且,它會更好,而(totalBytesRead =檔案大小做! )而不是while(bytesRead!= -1)?

+0

如果您正在複製內存塊,則不需要緩衝流。緩衝是爲了將較小的讀取/寫入轉變爲較大的讀取/寫入。 –

回答

3

我對這樣的事情典型循環如下所示:

int bytesRead; 
while ((bytesRead = input.read(buffer)) != -1) { 
    output.write(buffer, 0, bytesRead); 
} 

雖然我不通常像條件(循環或if)內執行任務,這是一個足夠常見的模式這個特別的用例很快就適應了它。

請注意,這裏的read僅僅是整個緩衝區 - 我不知道爲什麼你要限制它diskBlockSizeEstimate ...或者,如果你想,作爲最大的量,每次讀,只需創建具有該大小的緩衝區即可。

+0

但是不會在調用循環中最後一次調用.write(buffer,0,-1)嗎? (這是非法的http://developer.android.com/reference/java/io/BufferedOutputStream.html#write%28byte[],%20int,%20int%29)。或者實際上,我猜它不會調用該寫入(...,-1),因爲循環不會在該條件下重新輸入,但是它將永遠不會將最後一個字節寫入輸出? –

+1

@DavidDoria:不,它不會 - 因爲當賦值爲-1時,循環將退出而不是進入主體。 –

+0

對不起,我的觸發器太快了。我編輯了這個評論,問不就是從來沒有寫過上次讀取的字節嗎? –