Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java multiple connection downloading

I wanted to get some advice, I have started on a new project to create a java download accelerator that will use multiple connections. I wanted to know how best to go about this.

So far I have figured out that i can use HttpUrlConnection and use the range property, but wanted to know an efficient way of doing this. Once i have download the parts from the multiple connections i will then have to join the parts so that we end up with a fully downloaded file.

Thanks in advance :)

like image 352
Brendon Randall Avatar asked Feb 11 '10 08:02

Brendon Randall


2 Answers

  1. Get the content length of the file to download.
  2. Divide it according to a criteria (size, speed, …).
  3. Run multiple threads to download the file starting at different positions,
    and save them in different files: myfile.part1,  myfile.part2, …
  4. Once downloaded, join the parts into one single file.

I tried the following code to get the content length:

public Downloader(String path) throws IOException {
    int len = 0;
    URL url = new URL(path);
    URLConnection connectUrl = url.openConnection();
    System.out.println(len = connectUrl.getContentLength());
    System.out.println(connectUrl.getContentType());

    InputStream input = connectUrl.getInputStream();
    int i = len;
    int c = 0;
    System.out.println("=== Content ==="); 
    while (((c = input.read()) != -1) && (--i > 0)) {
        System.out.print((char) c);
    }
    input.close(); 
}

Here's a sample code to join the files:

public void join(String FilePath) {
    long leninfile=0, leng=0;
    int count=1, data=0;
    try {
        File filename = new File(FilePath);
        RandomAccessFile outfile = new RandomAccessFile(filename,"rw");
        while(true) {
            filename = new File(FilePath + count + ".sp");
            if (filename.exists()) {
                RandomAccessFile infile = new RandomAccessFile(filename,"r");
                data=infile.read();
                while(data != -1) {
                    outfile.write(data);
                    data=infile.read();
                }
                leng++;
                infile.close();
                count++;
            } else break;
        }
        outfile.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
}
like image 80
Syed M Shaaf Avatar answered Oct 21 '22 16:10

Syed M Shaaf


If you want to avoid joining segments after downloading you could use a FileChannel.
With a FileChannel, you can write to any position of a file (even with multiple threads).

So you could first allocate the whole file, and then
write the segments where they belong as they come in.

See the Javadocs page for more info.

like image 26
zockman Avatar answered Oct 21 '22 16:10

zockman