2010-05-13 51 views
1

我正在構建一個應用程序,我要在手機(移動)上下載大文件,但是如果文件的大小很大,我將得到異常套接字異常斷開的管道。使用java下載大文件

resp.setHeader("Content-length", "" + fileLength); 
    resp.setContentType("application/vnd.ms-excel"); 
    resp.setHeader("Content-Disposition","attachment; filename=\"export.mpr\""); 
    FileInputStream inputStream = null; 
try 
{ 
    inputStream = new FileInputStream(path); 
    byte[] buffer = new byte[1024]; 
    int bytesRead = 0; 

    do 
    { 
      bytesRead = inputStream.read(buffer, offset, buffer.length); 
      resp.getOutputStream().write(buffer, 0, bytesRead); 
    } 
    while (bytesRead == buffer.length); 

    resp.getOutputStream().flush(); 
} 
finally 
{ 
    if(inputStream != null) 
      inputStream.close(); 
} 

回答

0

如果你得到一個SocketException,問題不在於這裏的代碼,而是與底層的網絡協議。在這種情況下,「斷開的管道」意味着你失去了與服務器的連接 - 或者是因爲服務器掛起,互聯網連接不穩定或其他原因 - 並且read正在拋出異常,因爲它發生了成爲目前嘗試使用該連接的方法。

+0

我同意Etaoin,但我可以下載小文件說abt在kbs,但問題是當文件大小很大。 – angelina 2010-05-13 09:37:24

+0

那麼,文件越大,需要的時間越長,這意味着更可能出現零星問題。例如,如果您的連接平均每十秒重置一次,則一分鐘下載比一秒鐘下載更有可能看到它。 – Etaoin 2010-05-13 09:41:01

+0

謝謝,現在我該如何解決我的問題。我使用grrs連接在手機上下載文件,使用上面提到的代碼。我可以如何解決這個問題。 – angelina 2010-05-13 10:05:09

3

我不知道這是否與您的問題有關,但看起來您沒有正確使用read()read()在輸入結束時返回-1,即使有更多數據可用,也可能會讀取小於指定的字節數。我會建議,而不是使用

while ((bytesRead = inputStream.read(buffer, 0, buffer.length)) != -1) { 
    resp.getOutputStream().write(buffer, 0, bytesRead); 
} 

您的原始代碼風險結尾數據結束之前讀取循環,或致電write()bytesRead設置爲-1。此外,原始代碼中的offset變量似乎不必要;因爲您正在嘗試填充整個緩衝區,所以偏移量應始終爲0。

0

使用BufferedInputStream而不是FileInputStream,它爲您提供讀取數據的更多功能和靈活性。

0

您的應用程序的環境是什麼?我的意思是哪個AppServer,WebServer等

當通過Apache Httpd和Tomcat組合服務大文件時,我遇到了類似的問題。我的客戶正在使用正常的瀏覽器,我試圖發送分塊的數據。 (對於非常大的文件,我正在讀取一大塊字節並將其發送給客戶端)。

我的問題可能是因爲我在httpd和tomcat之間使用的ajp連接器。我從ajp切換到兩者之間的html連接器,它的工作就像一個魅力。