你好我尊敬的老年人:)
我的目标:通过在Java中使用多线程来下载URL资源,即使用URL中的多线程,即将单个文件下载到多个部分(非常类似于IDM的工作方式)&在下载结束时,将所有这些内容合并为1个最终文件。
技术使用: Java,RandomAccessFile,MultiThreading,InputStreams
问题: 文件已经下载了精确的KB大小,我已多次检查,但最终文件已损坏。例如,如果我下载一个图像,它会有点模糊,如果我下载.exe,它下载很好但是当我运行.exe文件时,它说"媒体损坏,重试下载"。
这是我的主代码,我用它来调用带有参数的线程类,例如fileName,连接的起始范围和结束范围,以及每个将分别更新自己的线程的JProgressBar
public void InitiateDownload()
{
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
uc.connect();
long fileSize = uc.getContentLengthLong();
System.out.println("File Size = "+ fileSize );
uc.disconnect();
chunkSize = (long) Math.ceil(fileSize/6);
startFrom = 0;
endRange = (startFrom + chunkSize) - 1;
Thread t1 = new MyThread(url, fileName, startFrom, endRange, progressBar_1);
t1.start();
//-----------------------------------------
startFrom += chunkSize;
endRange = endRange + chunkSize;
System.out.println("Part 2 :: Start = " + startFrom + "\tEnd To = " + endRange );
Thread t2 = new MyThread(url, fileName, startFrom, endRange, progressBar_2);
t2.start();
//-----------------------------------------
//..
//..
//..
//-----------------------------------------
startFrom += chunkSize;
long temp = endRange + chunkSize;
endRange = temp + (fileSize - temp); //add any remaining bits, that were rounded off in division
Thread t6 = new MyThread(url, fileName, startFrom, endRange, progressBar_6);
t6.start();
//-----------------------------------------
}
以下是 MyThread 类的 run()函数:
public void run() {
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();
fileSize = uc.getContentLengthLong();
inStream = uc.getInputStream();
int[] buffer = new int[ (int) totalDownloadSize ];
file.seek(startFrom); //adjusted start of file
这就是我认为问题在哪里 ,
run()继续......
for(int i = 0 ; i < totalDownloadSize; i++)
{
buffer[i] = inStream.read();
file.write(buffer[i]);
//Updating Progress bars
totalDownloaded = totalDownloaded + 1;
int downloaded = (int) (100 * ( totalDownloaded/ (float) totalDownloadSize)) ;
progressbar.setValue( downloaded );
}
System.err.println( Thread.currentThread().getName() + "'s download is Finished!");
uc.disconnect();
}
catch(IOException e) {
System.err.println("Exception in " + Thread.currentThread().getName() + "\t Exception = " + e );
}
finally {
try {
file.close();
if(inStream!=null)
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
现在文件已经完整下载,但正如我所说,其中一小部分已损坏。
立即,
如果我用for loop
循环替换while
,问题就完全解决了。
int bytesRead = 0;
byte[] buffer = new byte[ (int) totalDownloadSize ];
file.seek(startFrom); //adjusted start of file
while( (bytesRead = inStream.read(buffer) ) != -1 ) {
file.write(buffer, 0, bytesRead);
}
但是我需要for
循环测量每个线程下载多少文件&amp;我想升级各种各样的线索。
请帮我解决for循环逻辑。
或
如果您可以建议我如何在while
循环内升级Jprogressbars。我似乎无法找到一种方法来量化线程下载了多少文件...
我花了很多时间&amp;我现在非常累...
答案 0 :(得分:1)
您可以使用有效的while循环,然后跟踪读取的总字节数,如下所示:
int totalRead = 0;
while ((bytesRead = inStream.read(buffer)) != -1) {
totalRead += bytesRead;
file.write(buffer, 0, bytesRead);
progressBar.setValue((int)(totalRead / (double) totalDownloadSize));
}
请记住for (a; b; c) { ... }
等于a; while (b) { c; ... }
。