[Java]
Package Thread;
Import java.net. URL;
Import java.net. HttpURLConnection;
Import java. io .*;
Public class DownloadManager {
Static final long unitSize = 100*1024; // number of bytes allocated to each download thread
/**
* @ Param args
* 2012-10-8
* Void
* @ Throws IOException
*/
Public static void main (String [] args) throws IOException {
If (args. length! = 2 ){
System. out. println ("Usage: java DownloadManager URL localFileName ");
Return;
}
DownloadManager downloadManager = new DownloadManager ();
DownloadManager. doDownload (args [0], args [1]);
}
Public void doDownload (String remoteFileUrl, String localFileName) throws IOException {
Long fileSize = this. getRemoteFileSize (remoteFileUrl );
This. createFile (localFileName, fileSize );
Long threadCount = fileSize/unitSize;
System. out. println ("Total startup Threads" + (fileSize % unitSize = 0? ThreadCount: threadCount + 1) + "count ");
Long offset = 0;
If (fileSize <= unitSize) {// if the remote file size is smaller than or equal to unitSize
DownloadThread downloadThread = new DownloadThread (remoteFileUrl, localFileName, offset, fileSize );
DownloadThread. start ();
}
Else {// If the remote file size is greater than unitsize
For (int I = 1; I <= threadCount; I ++ ){
DownloadThread downloadThread = new DownloadThread (remoteFileUrl, localFileName, offset, unitSize );
DownloadThread. start ();
Offset = offset + unitSize;
}
If (fileSize % unitSize! = 0) // If division is not allowed, create another thread to download the remaining bytes.
{
DownloadThread downloadThread = new DownloadThread (remoteFileUrl, localFileName, offset, fileSize-unitSize * threadCount );
DownloadThread. start ();
}
}
}
// Obtain the Remote File Size
Private long getRemoteFileSize (String remoteFileUrl) throws IOException
{
Long result = 0;
HttpURLConnection httpURLConnection = (HttpURLConnection) new URL (remoteFileUrl). openConnection ();
HttpURLConnection. setRequestMethod ("HEAd ");
For (int I = 0; I <10; I ++ ){
If (httpURLConnection. getHeaderField (I). inclusignorecase ("Content-Length ")){
Result = Long. parseLong (httpURLConnection. getHeaderField (I ));
Break;
}
}
Return result;
}
// Create a file of the specified size
Private void createFile (String fileName, long fileSize) throws IOException {
File newFile = new File (fileName );
RandomAccessFile raf = new RandomAccessFile (newFile, "rw ");
Raf. setLength (fileSize );
Raf. close ();
}
}
[Java]
Package Thread;
Import java.net .*;
Import java. io .*;
Public class DownloadThread extends Thread {
Private String url = null; // the object to be downloaded
Private String file = null; // local storage path
Private long offset = 0; // offset
Private long length = 0; // Number of download bytes allocated to this thread
Public DownloadThread (String url, String file, long offset, long length ){
This. url = url;
This. file = file;
This. offset = offset;
This. length = length;
}
Public void run (){
Try {
HttpURLConnection httpURLConnection = (HttpURLConnection) new URL (this. url). openConnection ();
HttpURLConnection. setRequestMethod ("GET ");
HttpURLConnection. setRequestProperty ("RANGE", "bytes =" + this. offset + "-" + (this. offset + this. length-1 ));
BufferedInputStream bis = new BufferedInputStream (httpURLConnection. getInputStream ());
Byte [] buff = new byte [1024];
Int bytesRead;
While (-1! = (BytesRead = bis. read (buff, 0, buff. length ))){
This. writeFile (file, offset, buff, bytesRead );
This. offset = this. offset + bytesRead;
}
} Catch (IOException e ){
E. printStackTrace ();
}
}
// Write the byte array into the file in Random Access Mode
// FileName is the written file
// Offset indicates the offset of the file to be written.
// Bytes is the byte array to be written.
// RealLength is the actual number of bytes to be written (realLength <= bytes. length)
Private void writeFile (String fileName, long offset, byte [] bytes, int realLength) throws IOException
{
File newFile = new File (fileName );
RandomAccessFile raf = new RandomAccessFile (newFile, "rw ");
Raf. seek (offset );
Raf. write (bytes, 0, realLength );
Raf. close ();
}
}