【发布时间】:2014-05-09 16:09:15
【问题描述】:
尊敬的前辈您好:)
我的目标: 在给定一个 URL 的情况下,通过在 Java 中使用多线程下载一个 URL 资源,即将一个文件下载到多个部分(很像 IDM 的做法)并在末尾下载,将它们全部合并为 1 个最终文件。例如,如果一个图像是 260KB,我想将它下载到 2 个线程中,1st Thread 应该从 0KB 下载到 130KB 和 2nd Thread 应该从 131KB to 260KB 下载。 p>
技术使用: Java、RandomAccessFile、多线程、InputStreams
问题:此代码适用于 1 个线程,即如果我运行从 0 到 260KB 的单个线程。但是当我尝试分块下载时,出现以下错误:
-
它将下载额外的垃圾 KB,即对于 260KB 的文件,将下载 300+KB。
或
有时会下载 260KB,但文件已损坏,我无法打开图像。
请帮助我。整个星期以来我已经尝试了很多,但我似乎无法理解这个问题。
初始代码
void InitiaeDownload
{
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
uc.connect();
long fileSize = uc.getContentLengthLong();
System.out.println("File Size = "+ fileSize );
uc.disconnect();
//------------------
long chunkSize = (long) Math.ceil(fileSize/2);
long startFrom = 0;
long endRange = (startFrom + chunkSize) - 1;
System.out.println("Chunk Size = " + chunkSize);
System.out.println("Part 1 :: Start = " + startFrom + "\tEnd To = " + endRange);
Thread t1 = new MyThread(url, file, startFrom, endRange);
t1.start();
startFrom += chunkSize;
long temp = endRange + chunkSize;
endRange = temp + (fileSize-temp); //also add remaining bytes
System.out.println("Part 2 :: Start = " + startFrom + "\tEnd To = " + endRange );
Thread t2 = new MyThread(url, file, startFrom, endRange);
t2.start();
}
&现在,
线程类
class MyThread extends Thread {
private URL url;
private long startFrom;
private long range;
private InputStream inStream;
private RandomAccessFile file;
public MyThread(URL url, RandomAccessFile file, long startFrom, long range) //parameterized constructor
{
this.url = url;
this.file = file;
this.startFrom = startFrom;
this.range = range;
}
public void run() {
System.out.println("Thread Running..");
Thread.currentThread().setPriority(MAX_PRIORITY);
System.setProperty("http.proxyHost", "192.168.10.50");
System.setProperty("http.proxyPort", "8080");
HttpURLConnection uc = null;
try {
uc = (HttpURLConnection) url.openConnection();
uc.setRequestProperty("Range", "bytes="+startFrom+"-"+range);
uc.connect();
inStream = uc.getInputStream();
System.out.println("Starting Download");
int bytesRead = 0;
byte[] buffer = new byte[ (int) (range-startFrom) ];
file.seek(startFrom); //adjusted start of file
while( (bytesRead = inStream.read(buffer) ) != -1 ) {
file.write(buffer, 0, bytesRead);
}
System.err.println("Download Completed!");
uc.disconnect();
}
catch(IOException e) {
System.err.println("Exception in " + Thread.currentThread().getName() + "\t Exception = " + e );
}
} ///END OF run()
} ////END OF MyThread Class
【问题讨论】:
-
Android 所以没有适合你的 Java 7,对吗?
-
@fge 抱歉我没听懂...?
-
我的意思是,你可以使用新的文件 API 吗?
-
@fge 当然可以。我正在研究 Java7。
标签: java multithreading inputstream httpurlconnection java-io