论坛首页 Java企业应用论坛

多线程断点续传实践

浏览 64861 次
该帖已经被评为精华帖
作者 正文
   发表时间:2009-07-19  
这代码写的还有待改进,不过对MM,也算不错了
0 请登录后投票
   发表时间:2009-07-19  
好东西就要收起来以后再处理
0 请登录后投票
   发表时间:2009-07-19  
先赞一个,MM的代码写的不错。
但下来跑了一下,感觉还有些问题,主要就是在ChildThread中关于单块下载完成的判断上。
第一个问题如下,
if(count >= threadDownloadLength){  
                        hasFinished = true;  
                    }

这里count的类型是int,而threadDownloadLength得类型是long,一般来说不会有问题,但当下载的文件特别大(单块超过2.5G)的时候,count就会溢出。

第二个问题是,假设有如下场景,新建的下载任务,下载的第三块Thread3,startPosition为200,endPosition为300,下载到count为80的时候,发生一次异常,被catch块捕捉到之后,等待5秒钟继续循环下载,如下所示,startPosition会变成280。假设此时又发生一个异常,程序再次跑到下面的代码,这时startPosition会变成360,从而超过endPosition,程序便会错误的判断下载正常结束。最终导致的结果是,合并出的文件会缺失一部分。
			for (;;) {
				startPosition += count;

0 请登录后投票
   发表时间:2009-07-19   最后修改:2009-07-19
firefly.li 写道
先赞一个,MM的代码写的不错。
但下来跑了一下,感觉还有些问题,主要就是在ChildThread中关于单块下载完成的判断上。
第一个问题如下,
if(count >= threadDownloadLength){  
                        hasFinished = true;  
                    }

这里count的类型是int,而threadDownloadLength得类型是long,一般来说不会有问题,但当下载的文件特别大(单块超过2.5G)的时候,count就会溢出。

第二个问题是,假设有如下场景,新建的下载任务,下载的第三块Thread3,startPosition为200,endPosition为300,下载到count为80的时候,发生一次异常,被catch块捕捉到之后,等待5秒钟继续循环下载,如下所示,startPosition会变成280。假设此时又发生一个异常,程序再次跑到下面的代码,这时startPosition会变成360,从而超过endPosition,程序便会错误的判断下载正常结束。最终导致的结果是,合并出的文件会缺失一部分。
			for (;;) {
				startPosition += count;



1、count已修改为long型。
2、startPosition的设值位置确实不对,我现在把"startPosition += count;"放到了后面从inputStream.read()循环的里面。一旦读了数据,并往outputStream里面写入了,就重新设置startPosition的位置。
	while (!this.task.statusError
			&& (len = inputStream.read(b)) != -1) {
		outputStream.write(b, 0, len);
		
		count += len;
		startPosition += count;
		
		// 每读满4096个byte(一个内存页),往磁盘上flush一下
		if (count % 4096 == 0) {
			outputStream.flush();
		}
	}


呵呵,谢谢你的意见,提得非常好!
0 请登录后投票
   发表时间:2009-07-19  
gange 写道
楼主的代码风格很不错,我这里提点建议,也是很明显的一个问题,现在很多下载地址都做过处理,不能像你那样截取得到文件格式与名字,


我先暂时弄了一个过渡方案,如果截取不到名字,就用一个UUID代替。以后我再想想怎么弄吧。
0 请登录后投票
   发表时间:2009-07-19   最后修改:2009-07-19
代码应该把每个方法的代码行数都控制在10行之内。
不使用嵌套的控制块。
基本功有待提高啊。
0 请登录后投票
   发表时间:2009-07-20  
每下载线程一个临时文件?那要是1GB大文件分10线程下载最后合并也得老半天吧,建议用RandomFileAccess做单一临时文件。
0 请登录后投票
   发表时间:2009-07-20  
支持MM,pufan的建议不错
0 请登录后投票
   发表时间:2009-07-20  
解释得很详细,值得仔细阅读~~
0 请登录后投票
   发表时间:2009-07-20  
运行了几次  下载完都无法打开压缩包 而且不能把临时文件全删了  不知道是什么原因
没有抛任何异常
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics