-
「多线程下载」线程无法完整读取数据20
这是线程代码,每个线程负责下载文件的一段:
package download;
import java.io.*;
import java.net.*;
public class DownloadThread extends Thread{
private InputStream in; //网络下载文件输入流
private RandomAccessFile out; //下载文件输出流
private URL downURL;
private TaskInfo taskInfo;
private long startP;
private long block;
private int threadID;
private boolean finished=false;
private boolean error=false;
public DownloadThread(TaskInfo taskInfo,int threadID){
this.taskInfo=taskInfo;
this.threadID=threadID;
}
public boolean isFinished(){
return finished;
}
public boolean isError(){
return error;
}
public void run(){
HttpURLConnection http;
int errCount = 0; //报文申请错误计数
quit:
for(int i=0;; i++){
try{
if(i>0){
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"正在重新连接服务器......");
Thread.sleep(2000); //两秒后重新发起连接
}
}
catch(Exception e){
}
try{
downURL=new URL(taskInfo.getDownURL());
http=(HttpURLConnection)downURL.openConnection();
//setHeader(http);
http.setConnectTimeout(5000); //防止因为网络异常而僵死
http.setReadTimeout(5000);
startP = taskInfo.getDownPos()[threadID][0]; //更新线程进度信息(适用于重新连接服务器的情况)
block = taskInfo.getDownPos()[threadID][1];
String sProperty = "bytes=" + startP + "-";
http.setRequestProperty("Range",sProperty);
System.out.println("http response code: "+http.getResponseCode());
if(http.getResponseCode() != HttpURLConnection.HTTP_OK && http.getResponseCode() != HttpURLConnection.HTTP_PARTIAL){
error = true;
break;
}
in=http.getInputStream();
out=new RandomAccessFile(taskInfo.getSaveFilePath(),"rw");
}
catch(IOException e1){
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"报文申请错误!");
if((errCount++)>=19) break; //连续20次报文申请错误,判定线程错误,跳出for循环
continue; //线程报文申请错误,重新发起连接
}
errCount = 0;//重置计数
byte[] buffer=new byte[1024];
int len=0;
long localSize=0;
long step = 0;
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"开始下载");
try {
out.seek(startP);
step=(block>1024)?1024:block; //精确控制in.read所读取的最大长度,否则当block<1024时,len不准确,导致localSize出错。
while (((len = in.read(buffer,0,(int)step))>0)&&localSize<=block) { //一定要>0,不能>-1或!-1,因为不负责文件末段的线程完成后返回0
if(taskInfo.isStopped()) break;
if(taskInfo.isError()) break quit; //任一线程error,直接终止其他所有线程
out.write(buffer,0,len);
localSize+=len;
//修改文件下载线程进度信息
taskInfo.getDownPos()[threadID][0]=startP+localSize;
taskInfo.getDownPos()[threadID][1]=block-localSize;
long tmp_block=block-localSize;
step=(tmp_block>1024)?1024:tmp_block;
//更改下载文件长度
taskInfo.setDownLength(len);
}
System.out.println("线程"+threadID+" read len:"+len);
System.out.println("线程"+threadID+" block-localSize="+(block-localSize));
out.close();
in.close();
http.disconnect();
if(taskInfo.isStopped()){
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"暂停下载");
break;
}
else if((block-localSize)!=0){ //len=-1跳出while循环,猜测原因是url所对应的资源有变化。
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"获取数据错误");
error = true;
break;
}
else{
finished=true;
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"完成下载");
break; //下载完成,跳出循环,防止线程重新启动。
}
}
catch(Exception e2){ //in.read(buffer)发生异常,java.net.SocketTimeoutException: Read timed out
System.out.println("文件 ["+taskInfo.getFileName()+"] 线程"+threadID+"获取数据超时");
try{
out.close();
in.close();
http.disconnect();
}
catch(Exception e1){
}
continue; //线程下载出错,重新发起连接
}
}
if(errCount>19) error = true; //报文申请20次仍不成功,判定该线程错误
}
}
测试:下载pconline的软件
发现几个问题:
1、出现http response code是416(范围请求错误),但我调试发现请求的数据范围并没有错。
2、有时候,负责下载中间断数据的线程,在下载过程中in.read()返回-1,并且这时候数据并没有下载完整。「正常情况下应该不断读取数据,直到read()返回0对吧」
被这两个问题困扰很久,请大家不吝赐教,多谢!2013年3月28日 21:37
目前还没有答案
相关推荐
在IT领域,多线程是并发处理任务的关键技术,尤其在读取大文件时,能够显著提高程序的执行效率。本文将围绕“多线程读取文件”这一主题,结合给定的标签“源码”和“工具”,深入探讨如何在Java等编程语言中实现这一...
在IT领域,多线程是一种常见的编程技术,用于提高程序的执行效率,特别是在处理大量数据时。本示例中,我们关注的是如何在Delphi环境中使用TThread组件进行多线程编程,以便并行读取文本文件数据。下面将详细阐述这...
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据
在处理大数据量的文本文件时,单线程读取可能会导致程序响应慢或者占用过多系统资源,因此,采用多线程技术进行读取就显得尤为重要。 在“易语言多线程读取大文本文件”这个主题中,核心概念是多线程和文件I/O操作...
本源码示例是关于如何在易语言中实现多线程读取大文本文件,这对于处理大量数据或长时间运行的任务尤其有用。以下将详细介绍这一技术及其应用。 首先,理解多线程的概念至关重要。在单线程环境中,程序按照顺序执行...
在文件传输中,可以多线程下载大文件,提高下载速率。 总结来说,多线程读取大文件是提升系统性能的有效手段,它结合了并行处理和I/O操作优化,减少了整体处理时间。开发者应根据具体的应用场景和语言特性,选择...
然而,多线程编程也需要注意线程同步问题,防止数据竞争和死锁,确保数据的一致性和完整性。 在用户交互体验方面,本程序还引入了进度条功能。进度条能直观地展示任务的完成状态,给予用户反馈,提高用户体验。在...
本教程聚焦于如何利用多线程实现串口(Serial Port)读写数据及文件的读写操作,这对于理解和开发高效通信系统至关重要。 首先,我们要理解什么是串口通信。串口通信是一种基于串行数据传输的通信方式,它通过一条...
在C#编程中,开发人员经常需要处理网络数据的下载任务,特别是在大数据量或需要优化性能的情况下,多线程技术的应用变得尤为重要。本篇将详细探讨如何基于`HttpWebRequest`和多线程来实现一个高效的文件下载类。 ...
8. **IdHttpDownload.pas**:这个文件很可能包含了自定义的下载类,扩展了 TIdHTTP 功能,用于处理多线程下载的具体操作。 9. **httpdown.res**:这是一个资源文件,可能包含了应用程序的图标和其他资源。 在实现...
Qt Creator 多线程读取文件到程序显示 利用QT Creator多任务读取一个文档到程序里 为了防止直接读取文件里的内容太大而发生卡顿,于是多线程读取将更高效的解决这个问题。 效果图如下: 其中pro文件无需改动,...
在Java编程中,多线程导入Excel数据是一项常见的任务,特别是在大数据处理和高并发场景下。这个场景通常涉及到性能优化和资源管理,以确保系统稳定性和数据一致性。下面将详细阐述多线程导入Excel数据的核心知识点。...
在这个项目中,易语言被用来构建多线程下载器的核心逻辑,包括任务管理、线程控制、数据接收与合并等关键部分。 1. **任务管理**:在项目中,每个下载任务会被表示为一个独立的对象,包含文件URL、保存路径、已下载...
首先,多线程下载文件是一种提高下载速度的方法,通过将大文件分成多个小部分,每个部分由一个单独的线程负责下载,从而充分利用多核处理器的并行处理能力。在Java中,我们可以使用`java.util.concurrent`包中的`...
总结来说,"海康网络相机利用SDK多线程读取图像程序"是一个综合性的项目,涵盖了网络通信、图像处理、多线程编程等多个领域的技术,对开发者的技能要求较高。通过这样的实践,开发者不仅能深入理解海康威视SDK的使用...
以下将详细介绍“C#处理大容量数据,及多线程简单应用”这一主题。 首先,当我们面临大量数据时,一个关键的考虑点是避免阻塞主线程,尤其是对于UI(用户界面)应用。在C#中,长时间运行的任务会阻塞UI线程,导致...
而QThread是Qt提供的线程类,用于实现多线程编程,有助于提高程序的响应性和性能。 首先,我们需要了解如何在Qt中连接到MySQL数据库。Qt的SQL模块提供了QMYSQL driver,使得我们可以连接到MySQL服务器。在VS2010中...
在编程领域,多线程是提高程序执行效率和响应能力的一种常见技术,特别是在处理I/O密集型任务如网络下载时。Qt是一个强大的跨平台应用程序开发框架,提供了丰富的API来支持多线程编程。本篇文章将深入讲解如何使用Qt...
多线程读取摄像头并对图像进行处理(C++)
Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个部分并同时下载,显著提高了下载速度。在Java中实现多线程下载器涉及许多关键概念和技术,包括线程、并发控制、网络I/O...