Creating Java Download Application

On internet activity, we often do download or upload. Download is an internet activity which takes a file from remote computer to our local computer.

Basically, when we download a file from a remote computer or a server, actually our computer reading byte by byte of a file that we want to download. And after all the byte read then the computer will pack it onto a file that contains perfectly same with the file that we like to download.

With this concept, let’s try to make a little experiment and this experiments will implement all the steps above, we can complete this experiment with another steps that we can gather base on our knowledge that we can find out from the above download process concept.

Let’s try to arrange the steps:

  1. URL identification.

To download a file, we need a valid URL address for sure, and the path location of a file that we want to download. Example: http://www.wayofmuslim.com/ebook-islam/AlQuranDigital.zip. this have a meaning that we want to download a file named AlQuranDigital.zip from a remote computer wayofmuslim.com and the path location of this file at ebook-islam/

  1. The size of file.

Each file that we want to download, have to find out the size of it. The purpose of this are we will be able to compare the bytes length that already read and stored in our local computer with the file that exist on remote computer, so we can find out whether the byte we have downloaded is corrupted or not before we can pack it up onto a file.

  1. The content type of file.

This is optional, we can use this concept or not, it’s an option. But knowing the content type of a file in internet technology is the basic knowledge.

With those concept actually we can create our own application that have ability to download a file from a remote computer, yes we can, because the download concept is that simple.

Now let’s proof it by arrange a scenario based on the concept above to create our own Java Download Application. The scenario is:

  1. Identifying URL.

Checking whether the supplied URL valid or not, we will use URL class that exist on Java.

  1. Valid URL.

If the URL is valid, then go straight to create a HTTP Connection to check whether our computer is connected to the internet or not. And if the URL is not valid then just exit the application and show some screens out telling that the connection is not available.

  1. Identifying the Content Type

If the Http Connection status is good, meaning that the host or remote computer can be contacted, the next step is identifying the content type of a file that we would like to download. In this try-it-out let’s just limit it, if the content type of a file is text/html, then we don’t have to download it. Why? The Http Status 404 (File Not Found) can be occurred on a file that we want to download, and we don’t need this html page to download to our computer rite?

  1. Identifying the byte length (Content Length).

Just because we will to read byte by byte of file that we want to download, so it’s very important to store information of a byte length of the file that we want to download into a variable. And for the next usage this information can be some useful things in order to compare the byte length of downloaded byte with the length of byte that exist on remote computer, to find out whether the downloaded file corrupted or not.

  1. Reading byte by byte.

This is the essential things on our try-it-out. Our application should have an ability to read byte by byte of the file that we want to download and the result of the bytes reading will put on a variable which have byte data-type. The way of bytes reading is using the looping from 0 to the content length that we have store it into a variable before.

  1. Comparing local file to a remote file.

The next step is comparing the length of bytes that already read with the length of byte that stored before on a variable. If the both are not same that’s mean the downloaded file is corrupted and this byte will not be packed onto a file.

  1. Pack the read bytes.

After we knew exactly that the length of read bytes is similar to byte length of remote computer, so it’s time to pack it up onto a file. Let’s just make it easier by naming the file exactly same with the name of file that exist on remote computer.

Using the above scenario, let’s try to code just like the source code below:

package org.mojo.download.agent;

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: May 2, 2009
 * Time: 11:39:49 AM
 * To change this template use File | Settings | File Templates.
 */
public class SingleDownloadAgent {

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage : java SingleDownloadAgent <URL>" );
            return;
        } else {
            SingleDownloadAgent agent = new SingleDownloadAgent();
            try {
                doDownload(args[0]);
            } catch (IOException e) {
                System.err.println("Exception e");
            }
        }
    }
    public static void doDownload(String sURL) throws IOException {
       URL u = null;
        //try URL
        try {
            u = new URL(sURL);
        } catch (MalformedURLException ex) {
            System.err.println("Malformed URL : " + ex);
            return;
        }
        catch (IOException ex) {
            System.err.println("An Error Occured : " + ex);
            return;
        }
       //reading Connection
        URLConnection uc = null;
        try {
            uc = u.openConnection();
            //identifying connection
            uc.connect();
        } catch (IOException e) {
            System.out.println("Cannot Connect: Please Check Connection");
            return;
        }

        String contentType = uc.getContentType();
        System.out.println("contentType :" + contentType);

        int contentLength = uc.getContentLength();
        if (contentType.startsWith("text/html") || contentLength == -1) {
            throw new IOException("This is html file.");
        }

        //collecting byte in var data
        InputStream raw = uc.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] data = new byte[contentLength];
        int bytesRead = 0;
        int offset = 0;
        while (offset < contentLength) {
            bytesRead = in.read(data, offset, data.length - offset);
            if (bytesRead == -1) break;
            offset += bytesRead;
        }
        in.close();

        //file corrupted
        if (offset != contentLength) {
            throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes ? File Corrupted…");
        }

        //writing byte data to a file
        String filename = u.getFile();
        filename = filename.substring(filename.lastIndexOf('/') + 1);
        FileOutputStream fout = new FileOutputStream(filename);
        fout.write(data);
        fout.flush();
        fout.close();

    }
}

On the above source-code we have two methods, which is the main method and the doDownload method with sURL string as it’s parameter. Let’s discuss it line by line the above source-code:

As usual, at the beginning of the code we declare the package where this class is located and the declaration of imported class that we will need later. And then on the main method we check whether the URL parameter supplied when this class is called. Indeed, this application designed has to supply the URL parameter when this application called.

package org.mojo.download.agent;

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: May 2, 2009
 * Time: 11:39:49 AM
 * To change this template use File | Settings | File Templates.
 */
public class SingleDownloadAgent {

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage : java SingleDownloadAgent <URL>" );
            return;
        } else {
            try {
                doDownload(args[0]);
            } catch (IOException e) {
                System.err.println("Exception e");
            }
        }
    }
………

On this main method, showed that if the URL parameter is not supplied then this application will print out the message of application usage and then directly quit. And if the URL parameter supplied then the application will continuing call the doDownload method with args[0] as it’s parameter.

Now let’s take a look at the second method which is doDownload methods:

   ………
   public static void doDownload(String sURL) throws IOException {
       URL u = null;
        //try URL
        try {
            u = new URL(sURL);
        } catch (MalformedURLException ex) {
            System.err.println("Malformed URL : " + ex);
            return;
        }
        catch (IOException ex) {
            System.err.println("An Error Occured : " + ex);
            return;
        }
    ………

On these lines we run out first scenario which is validating the URL, and we put it on a try-catch block. Why we put it on try-catch block? Because we want to know if the error occurred, where it will be happen.

…………
        //reading Connection
        URLConnection uc = null;
        try {
            uc = u.openConnection();
            //identifying connection
            uc.connect();
        } catch (IOException e) {
            System.out.println("Cannot Connect: Please Check Connection");
            return;
        }

        String contentType = uc.getContentType();
        System.out.println("contentType :" + contentType);

        int contentLength = uc.getContentLength();
        if (contentType.startsWith("text/html") || contentLength == -1) {
            throw new IOException("This is html file.");
        }
…………

And after that, on the lines above code we check the connection to host or remote computer by put it once again on try-catch block, and then the next line we find out the content type of the file that we want to download and put the information on a string variable called contentType. And then we check the content length that we want to download and put in on a integer type variable. And the next lines is continue by the branching to make a decision if the content typeof the file is type/html type, then just quit the application.

    …………
        //collecting byte in var data
        InputStream raw = uc.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] data = new byte[contentLength];
        int bytesRead = 0;
        int offset = 0;
        while (offset < contentLength) {
            bytesRead = in.read(data, offset, data.length - offset);
            if (bytesRead == -1) break;
            offset += bytesRead;
        }
        in.close();

        //file corrupted
        if (offset != contentLength) {
            throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes ? File Corrupted…");
        }
    …………

On the lines above, we can see the reading of byte by byte do by our application, using the open up the output-stream and then read the output stream by looping byte and using the content length as it limitation, and then put it the read result into a data variable that have byte data-type. And after the read process is finished the output-stream is closed and then we create a statement to compare the length of read bytes that stored on offset variable with the contentLength variable.

…………
        //writing byte data to a file
        String filename = u.getFile();
        filename = filename.substring(filename.lastIndexOf('/') + 1);
        FileOutputStream fout = new FileOutputStream(filename);
        fout.write(data);
        fout.flush();
        fout.close();

    }
…………

And this is the last codes that we have created, on this codes we pack up the bytes that we have read and stored into a data variable before, into a file. To naming the file, we just named as a same filename that we want to download.

That’s it, our try-it-out for this time. There’s still a lot that we can explore more from this little experiments, such as we can build a GUI as its interface, or adding some progress bar animation, etc. Please explore more of this concept to creating more perfect things.

 

 

Hope it will be useful.

Menteng, March 3rd 2009

 

Josescalia.

One thought on “Creating Java Download Application

  1. Pingback: Creating Java Download Application | XML Developer

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s