2012-04-26 86 views
1

嘗試使用java下載pdf時出現錯誤。我知道有類似的問題,但不像我的具體問題。java.io.IOException:通過https下載pdf時出現EOF過早

我的代碼片段:

URL url = new URL("https://.../abc.pdf"); 
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
... 
InputStream in= conn.getInputStream(); 
ByteArrayOutputStream out = new ByteArrayOutputStream(4096); 
byte[] buf = new byte[4096]; 
int bytesRead = 0; 
while ((bytesRead = in.read(buf)) != -1) { 
    out.write(buf, 0, bytesRead); 
} 

療法服務器響應頭:

X-AspNet-Version:2.0.50727 
Transfer-Encoding:chunked 
Date:Thu 26 Apr 2012 12:07:59 GMT 
Content-Disposition:attachment; filename=abc.pdf 
Set-Cookie:Language=en-gb; path=/ 
Connection:Keep-Alive 
Content-Type:application/octet-stream 
Server:Microsoft-IIS/6.0 
X-Powered-By:ASP.NET 
Cache-Control:private 

異常(在in.read(buf)):

Exception in thread "main" java.io.IOException: Premature EOF 
    at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:556) 
    at sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:600) 
    at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:687) 
    at java.io.FilterInputStream.read(FilterInputStream.java:133) 
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:2959) 
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:2953) 

的代碼適用於幾乎所有的情況下,不得不已被使用數千次。但在極少數情況下,我會得到這個例外。但我可以用瀏覽器下載pdf。另外,如果我把PDF放在我自己的服務器上,我可以用我的代碼下載它。因此,它必須與服務器提供此pdf的方式有所不同。

也許它與Transfer-Encoding:chunked有關?

有沒有人有一個想法,我可以嘗試得到這個固定的?

回答

3

這似乎是一個與java分塊處理有關的bug。許多人通過一次讀取一個字節來解決問題,並將讀取內容放入EOFException的try-catch中。

+1

我只是試圖將緩衝區大小設置爲1:'byte [] buf = new byte [1];'但是會發生同樣的異常。我會嘗試嘗試抓住現在。 – morja 2012-04-26 12:43:00

+0

它實際上工作,如果我忽略異常,流仍然完全加載。即使有更大的緩衝區。謝謝你的提示!如果緩衝區不是1,你認爲在某些情況下可能會導致問題嗎?我可以依靠忽略異常嗎? – morja 2012-04-26 12:50:34

+0

如果錯誤僅發生在第一塊(如我所想):沒問題,只是忽略異常。一般來說:是的。 – Luca 2012-04-26 12:54:52

0

我認爲你應該需要這個代碼。

try { 
}catch(IOException e) { 
} finally { 
    try { 
    if (in != null) 
     in.close(); 
    }catch(Exception e) { 
    } 
} 

或者嘗試在Apache庫中使用IOUtils.close。

finally { 
    IOUtils.close(in); 
    } 

我發生過同樣的事情。但現在修復它。