Hello My Respected Seniors :)
My Goal: Download a URL Resource, given a URL, by using Multi-Threading in Java, i.e. download a single file into multiple pieces (much like how IDM does) & at the end of download, combine all of them to 1 final file. For instance, if an Image is of 260KB, I want to download it into 2 threads for which, 1st Thread
should download from 0KB to 130KB & 2nd Thread
should download from 131KB to 260KB
.
Technology Using:
Java, RandomAccessFile, MultiThreading, InputStreams
Problem: This code works for 1 thread, i.e. If I run a single thread that starts from 0 to 260KB. But when I try to download it in chunks, following errors occur:
It will download extra garbage KBs, i.e. for a 260KB file, 300+KB will be downloaded.
OR
Sometimes exact 260KB are downloaded, but file is corrupt, I can't open the Image.
Please help me. I've tried alot since the whole week & I can't seem to understand the problem.
INITIAL CODE
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();
}
& Now,
THREAD CLASS
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