[速度 VS 准确] 下载时保存下载进度

2016-10-13 10:09:05 +08:00
 814084764

在写下载模块,遇到一个问题:下载的时候如何又快又准确地记录下载的进度?

缘由:记录下载进度是为了下次继续下载时做文件校验,比如有没有被篡改。

目前的方案:(伪代码)

while(true)

{

byte[] buffer = connection.read();

file.write(buffer);

database.save(file.length());

}

出现一个问题:

如果不加 database.save ,下载速度可以达到正常的带宽速度。

如果加了,下载速度就会慢,并且很明显。

但是为了做校验,肯定需要 [实时] 保存下载的文件大小。

我想用一个 tempValue [实时] 记录一下进度,最后再刷到数据库中。

但是有个问题:如果程序异常终止,就会导致 tempValue 没有被刷到数据库中。

这样的话,有什么比较好的解决方案??

3032 次点击
所在节点    程序员
14 条回复
bigboyq
2016-10-13 10:17:00 +08:00
亲,你这个肯定会慢,因为 database save 方法被频繁调用,而且是 block 的,如果你把 database save 异步就不会影响,或者定量写入,比如 1MB 写一次,也会降低影响。
异常的问题可以通过异常处理模块补充。
814084764
2016-10-13 10:28:00 +08:00
@bigboyq 异常的地方肯定有很多,除了下载模块的异常,还有其他模块的异常,如何去做补充?
做一个全局的接收异常的方法?有些未捕获到的异常,又怎么处理呢?
所以感觉异常这块的处理还是有点麻烦呢。。。束手无策的赶脚。
要不就是改成写入到轻量级的文件中?
Karblue
2016-10-13 13:31:06 +08:00
不要写完就刷新硬盘。 IO 操作是很费时间的。存到缓存。然后再把缓存定时写出。
例如:把文件数据暂时存在全局变量中。开单独的线程去写出全局变量的文件
lrh3321
2016-10-13 13:44:03 +08:00
不支持 Linux ,我还是继续用 命令行吧
lrh3321
2016-10-13 13:45:46 +08:00
回错了,要回另外个帖子的。
===============
我觉得做个几 MB 的缓存,满了再写入磁盘。丢数据也就是丢缓存里这几 MB
limhiaoing
2016-10-13 13:46:30 +08:00
个人观点这个方法不可行。
可以这么做,数据库记录已下载大小和 hash ,先写下载的数据到磁盘后记录下载进度和 hash 。
limhiaoing
2016-10-13 13:49:58 +08:00
这样既是异常终止在写完下载数据和记录下载进度之间也不要紧,根据上次记录的下载进度丢弃多余的数据,校验记录的 hash 即可。
limhiaoing
2016-10-13 13:51:35 +08:00
我估计迅雷的断点续传是用类似的方法,不过因为它是分块下载,所以 hash 应该也是分块计算的。
ryd994
2016-10-13 14:46:24 +08:00
其实简单办法就是检查当前文件大小
直接从那个长度开始
这也是 wget 的做法
至于校验数据完整性……除非重新下一遍,否则 http 协议本身不含 checksum 做不到
bigboyq
2016-10-13 18:36:40 +08:00
再起一个线程做 database.save 就好了,但是你又回来这里问数据库 update 慢怎么办。。。。。。
icedx
2016-10-13 18:56:18 +08:00
别说我不友善啊
你是不是 SS
database.save(file.length());
你这样能不慢么
dlllcs
2016-10-13 22:35:50 +08:00
我觉得可以新建一个 Buffer ,大小差不多 32M 这样,每下载 32M 或者达到了 5 秒钟,就刷新进文件,这样比较好吧,这样 IO 比较少,而且丢数据也就丢最近几秒钟的数据
limhiaoing
2016-10-13 23:00:08 +08:00
单单靠文件长度来判断文件是否被篡改是不可靠的,文本被篡改不一定会导致文件长度改变。
即使你这两句之间没有可能抛出异常,但是断电呢?
file.write(buffer);
database.save(file.length());
所以,记录文件长度只能用于丢弃多余的数据,而不能用来校验文件是否被篡改。
用 hash+长度来记录已下载的文件就不需要实时的去保存长度了。可以每下载 10MB 保存一次,这样如果进程异常结束,最多就是丢弃 10MB 的数据。
814084764
2016-10-14 10:03:11 +08:00
@icedx 是有点傻。。哈哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/312415

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX