繁体   English   中英

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

[英]How to resume a interrupt download with 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 恢复中断下载?

来自评论

 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 的起始32,243,658 ,并下载了剩余的210,930,449字节,最终得到一个243,174,107字节的文件。

好吧,不,它最终得到了一个至少有243,204,042字节的文件,即29,935字节太多,因为代码总是写入完整buffer ,即使缓冲区没有被完整读取。

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

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM