Chapter 33: Creating a Download Manager in Java 973
are organized into numeric ranges of 100, and the 200 range indicates success. The server ’s
response code is validated for being in the 200 range by callingconnection.getResponseCode( )
and dividing by 100. If the value of this division is 2, then the connection was successful.
Next,run( )gets the content length by callingconnection.getContentLength( ). The
content length represents the number of bytes in the requested file. If the content length is
less than 1, theerror( )method is called. Theerror( )method updates the download’s status
toERROR, and then callsstateChanged( ). ThestateChanged( )method will be described
in detail later.
After getting the content length, the following code checks to see if it has already been
assigned to thesizevariable:
/ Set the size for this download if it
hasn't been already set. /
if (size == -1) {
size = contentLength;
stateChanged();
}
As you can see, instead of assigning the content length to thesizevariable unconditionally,
it only gets assigned if it hasn’t already been given a value. The reason for this is because
the content length reflects how many bytes the server will be sending. If anything other than
a 0-based start range is specified, the content length will only represent a portion of the file’s
size. Thesizevariable has to be set to the complete size of the download’s file.
The next few lines of code shown here create a newRandomAccessFileusing the filename
portion of the download’s URL that is retrieved with a call to thegetFileName( )method:
// Open file and seek to the end of it.
file = new RandomAccessFile(getFileName(url), "rw");
file.seek(downloaded);
TheRandomAccessFileis opened in “rw” mode, which specifies that the file can be
written to and read from. Once the file is open,run( )seeks to the end of the file by calling
thefile.seek( )method, passing in thedownloadedvariable. This tells the file to position
itself at the number of bytes that have been downloaded—in other words, at the end. It’s
necessary to position the file at the end in case a download has been resumed. If a download
is resumed, the newly downloaded bytes are appended to the file and they don’t overwrite
any previously downloaded bytes. After preparing the output file, a network stream handle
to the open server connection is obtained by callingconnection.getInputStream( ), as
shown here:
stream = connection.getInputStream();
The heart of all the action begins next with awhileloop:
while (status == DOWNLOADING) {
/ Size buffer according to how much of the
file is left to download. /
byte buffer[];
if (size - downloaded > MAX_BUFFER_SIZE) {
buffer = new byte[MAX_BUFFER_SIZE];