java - 如何使用RandomAccessFile恢复中断下载?

标签 java download randomaccessfile

我想使用 RandomAccessFile 进行中断下载。这是代码

HttpGet httpget = HttpUtil.buildGet(URL)
httpget.setHeader("RANGE", "bytes=" + (position) + "-");
CloseableHttpResponse response = HttpClients.createDefault().execute(httpget) 
HttpEntity entity = response.getEntity();

int totalLen = 0;
InputStream is = entity.getContent();
RandomAccessFile writeFile = new RandomAccessFile(desc, "rw");
writeFile.seek(position);
byte[] buf = new byte[65536];
totalLen = 0;
int len = is.read(buf);
while (len > 0) {
   totalLen += len;
   writeFile.write(buf);
   len = is.read(buf);
}
response.close();
is.close();
writeFile.close();

HttpRequest返回206并且下载成功完成,但是我得到了一个错误的文件,该文件比源文件大得多,我无法打开它。 这段代码有什么问题?如何使用 RandomAccessFile 恢复中断下载?

最佳答案

来自comment :

Accept-Ranges: bytes
ETag: W/"243174107-1583744547157"
Last-Modified: Mon, 09 Mar 2020 09:02:27 GMT
Content-Range: bytes 32243658-243174106/243174107
Content-Type: application/zip
Content-Length: 210930449

该请求指定了 32,243,658 的起始位置,并下载了剩余的 210,930,449 字节,最终得到一个 243,174,107 字节的文件。

嗯,不,它最终得到的文件至少 243,204,042 字节,即 29,935 字节太多,因为代码总是写入完整 缓冲区,即使缓冲区未完全读取。

文件很可能比这个大得多,因为数据以较小的 block 形式通过网络传输,因此在许多情况下缓冲区可能没有填充 65,536 字节read() 调用。

read() 返回 len 值是有原因的。您的代码应该是:

writeFile.write(buf, 0, len);

此外,您应该使用 try-with-resources,并且内联 read() 调用很常见,因此不会重复,例如代码应该是:

int totalLen = 0;
try (RandomAccessFile writeFile = new RandomAccessFile(desc, "rw")) {
    writeFile.seek(position); // should use value from response header here, not requested value
    try (InputStream is = entity.getContent()) {
        byte[] buf = new byte[65536];
        for (int len; (len = is.read(buf)) > 0; ) {
            totalLen += len;
            writeFile.write(buf, 0, len);
        }
    }
}
response.close();

关于java - 如何使用RandomAccessFile恢复中断下载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61075227/

相关文章:

java - 如何使用 Spring MVC 返回文本文件?

java - 为什么使用 ImageIO 下载的文件比浏览器下载的文件小?

perl - 为什么我用 Perl 编写的图像下载 CGI 脚本不起作用?

swift - 当应用程序在 iOS12 中进入后台时,URLSessionDelegate 的 didWriteData 不调用

java - 您可以使用 RandomAccessFile 访问远程 FTP 服务器上的文件吗?

java - 为什么 -classpath 选项在 java 1.8 上不起作用

java - 是否有一种独立于格式的方法来处理 JVM 上的文件?

java - 这种获取排序列表中最接近数字的方法是否最有效?