读书人

java 实现多线程上载(2)

发布时间: 2012-10-10 13:58:11 作者: rapoo

java 实现多线程下载(2)

上篇日志中中写了多线程下载的基本技术路线和主要难点,这里贴出代码。

package Thread;import java.net.URL;import java.net.HttpURLConnection;import java.io.*;public class DownloadManager {static final long unitSize=100*1024;//分配给每个下载线程的字节数/** * @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("共启动线程"+(fileSize%unitSize==0?threadCount:threadCount+1)+"个");long offset=0;if (fileSize<=unitSize) {//如果远程文件尺寸小于等于unitSizeDownloadThread downloadThread=new DownloadThread(remoteFileUrl,localFileName,offset,fileSize);downloadThread.start();}else {//如果远程文件尺寸大于unitsizefor (int i = 1; i <=threadCount; i++) {DownloadThread downloadThread=new DownloadThread(remoteFileUrl, localFileName, offset, unitSize);downloadThread.start();offset=offset+unitSize;}if(fileSize%unitSize!=0)//如果不能整除,则需要再创建一个线程下载剩余字节{DownloadThread downloadThread=new DownloadThread(remoteFileUrl, localFileName, offset, fileSize-unitSize*threadCount);downloadThread.start();}}}//获取远程文件的大小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).equalsIgnoreCase("Content-Length")){result=Long.parseLong(httpURLConnection.getHeaderField(i));break;}}return result;}//创建指定大小的文件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();}}


package Thread;import java.net.*;import java.io.*;public class DownloadThread extends Thread{private String url=null;//待下载的文件private String file=null;//本地存储路径private long offset=0;//偏移量private long length=0;//分配给本线程的下载字节数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();}}//将字节数组以随机存取方式写入文件//fileName是被写入的文件//offset代表写入文件的位置偏移量//bytes是待写入的字节数组//realLength是实际需要写入的字节数(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();}}


读书人网 >编程

热点推荐