【发布时间】:2012-11-09 18:49:04
【问题描述】:
如果文件是特定内容类型,我正在尝试从 URL 下载文件。该 URL 可以提供 html 或 pdf 页面,我只想保存 pdf 文件。我的尝试如下:
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
String contentType = connection.getContentType();
if (contentType.equals("application/pdf")) {
org.apache.commons.io.FileUtils.copyURLToFile(url, file);
}
contentType 被正确提取,但对copyURLToFile(url,file); 的调用导致以下异常:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.FilterInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
at org.apache.commons.io.FileUtils.copyURLToFile(FileUtils.java:848)
如果我删除用于获取 contentType 的代码行,并且只调用copyURLToFile(url,file),则文件已成功下载并保存。我是否以某种方式错误处理了我的HttpURLConnection,导致我的连接被重置?
我还注意到,如果我在if(contentType.equals("application/pdf") 行上设置断点并等待几秒钟,那么对copyURLToFile 的调用会成功,而不会重置连接。我是否引入了某种总是失败的竞争条件?
【问题讨论】:
-
在获取内容类型或使用 connection.setReadTimeOut 播放后重新连接
-
我认为HEAD 不应该返回文件的内容。
-
对
copyURLToFile的调用会创建一个新连接,因此它不应使用 HEAD 请求从 URL 获取输入流。