【问题标题】:Http java file download problemHttp java文件下载问题
【发布时间】:2023-03-31 17:22:01
【问题描述】:

尝试使用 apache httpclient 库下载文件,结果文件比原始文件小(大约 32-32kb,当正常文件大小为 92-93 时)并且无法在 pdf 查看器中正常打开。 有人可以解释一下为什么会发生这种情况吗? (使用firefox下载这个文件有时会导致文件被完全下载,有时会被部分下载)

这是我用来通过 URL 下载文件的代码

    URL url = new URL("pathtofile");
    final URLConnection connection = url.openConnection();

    final InputStream is = connection.getInputStream();
    FileOutputStream fos = new FileOutputStream("C://result1.pdf");

    byte buffer[] = new byte[1024];
    int bytesRead; 
    while ((bytesRead = is.read(buffer)) >= 0) {        
        fos.write(buffer, 0, bytesRead);
    }
    fos.flush();
    fos.close();
    is.close();

附:尝试使用 HttpClient apache 库下载此文件,结果相同。

更新:使用网络工具监控流量我发现通过 Firefox 和应用程序接收文件之间的区别。

Firefox 的第一个 HttpPayloadLine 是:

HTTPPayloadLine: 83 Td /F2 5.80476 Tf (A:\040Asinis\04017.12.10\04008:32\040laboratorij) Tj 100 Tz 1 1 1 rg /F1 5.80476 Tf 0 0 0 rg 104.4856 0 Td <0145> Tj 1 1 1 rg 0 0 0 rg 3.62799 0.72565 Td /F2 5.80476 Tf (\040) Tj 1 1 1 rg 0.83137 0.81569 0.78431 RG ET 51

应用程序首先 HttpPayload 是

HTTPPayloadLine: CWgC,ú&amp;ÿ3@Î"ݯV¨®~×&gt;×)\ªleÚlµï½ci ¤Ãð'È/CÈAø¯ª ÍübA«1Ãÿ Åç«VɬZòYóóy7»ÇH.o²e<qZna3l±°¥þ6ñþ[2YÚ1ì³Eë-ÓÊÏ$y:tÎà![ËÅS¤¿É¡¢è,þ|ºs¨)@¢Qâ¯ÝF~}oµÒ>¦ OAxz³äÒ.ß9 æÃZ¤ùÒ¨*«øUή+4×

此测量是通过 Microsoft 网络监视器进行的

上次更新毕竟是服务器问题,他们修复后文件下载成功

【问题讨论】:

  • 如果您阅读 URL 连接输入流,您将阅读来自服务器的“所有内容”。如果“pathtofile”是一个 http 请求,则服务器输出将包含一些 pdf 查看器无法处理的标头信息。到目前为止下载的文件的内容是什么?它以“%PDF”开头?
  • 好奇:HTTP 响应中是否有 Content-Encoding 标头?
  • 响应中没有 Content-Encoding 标头
  • 关于 firefox 有时可以正常下载,有时不能,如果您可以访问详细信息,我会进一步调查服务器。

标签: java http url download httpclient


【解决方案1】:

试试改成

while ((bytesRead = in.read(buffer)) != -1) {
 byte[] tmp = ArrayUtils.subarray(buffer, 0, bytesRead);
 fos.write(tmp);
}

你得到了 0 个字节,但这并不意味着它完成了。也只写你收到的字节而不是缓冲区。

【讨论】:

  • java.io.OutputStream 已经提供了一个write(byte b[], int off, int len) 方法。
  • yip 我知道只是想更清楚地说明我在做什么。 fos.write(buffer, 0, bytesRead)
【解决方案2】:

我发现的第一件事是检查is.read(buffer) &gt; 0 是否错误,因为它可能(至少在理论上)返回 0,即使它没有到达文件末尾。当到达 EOF 时,InputStream.read() 将返回 -1,因此请进行比较 &gt;= 0

编辑: 我发现的第二件事(有点晚了,因为它已经在其他答案中注意到了)是你正在将整个缓冲区写入输出流,无论它实际上有多少受到最新读取操作的影响。尝试类似:

byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ( (bytesRead = in.read(buffer)) >= 0 ) {
    out.write(buffer, 0, bytesRead);
}

【讨论】:

  • @artjomka:您是否也像我最近的编辑或 Pintac 的回答一样修改了您的代码?
  • 我修改了它,就像你最近的编辑一样(并用更改更新主帖子)
【解决方案3】:

也许阅读错误流可以给你一些信息:

connection.getErrorStream();

【讨论】:

  • 找不到 URLConnection 类的 getErrorStream 方法
  • 对,就是HttpURLConnection的一个方法。如果您的连接是 HTTP,请执行以下操作:((HttpURLConnection)connection).getErrorStream();
  • 这个方法在我的情况下返回 null
【解决方案4】:

你能改用org.apache.commons.io.FileUtils.copyURLToFile(URL, File)吗?

【讨论】:

    猜你喜欢
    • 2011-04-15
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2012-06-20
    相关资源
    最近更新 更多