使用RandomAccessFile实现多线程下载

来源:互联网 发布:煽扇除霾 知乎 编辑:程序博客网 时间:2024/06/14 18:29

使用写流来下载网上的资源,用多线程对资源进行下载。


     第一步:创建两个java脚本,一个服务器,一个客户端

首先推出多线程下载的实现原理


  第二步:服务器部分   继承  Thread 

            1、定义四个变量(线程id、文件下载的路径、文件保存的路径、单个线程下载的数据量)

public int id;//线程idpublic URL url;//文件下载的路径public File file;//文件保存的路径public int singleThreadNum;//单个线程下载的数据量
             2、定义构造方法

public DownThread(int id, URL url, File file, int singleThreadNum) {this.id = id;this.url = url;this.file = file;this.singleThreadNum = singleThreadNum;}
              3、实现run方法

@Overridepublic void run() {}
                4、在run方法中实例化RandomAccessFile随机读写类,参数中放入file文件以及"rwf";

@Overridepublic void run() {
            RandomAccessFile raf=new RandomAccessFile(file, "rwd");
}

             5、开始计算每个线程下载的开始位置与结束位置

        int start=id*singleThreadNum;        int end=(id+1)*singleThreadNum;
            6、通过从客户端传递过来的URL获取下载的链接,url是在客户端中调用构造方法后传到服务器的值,然后打开链接
      HttpURLConnection conn=(HttpURLConnection) url.openConnection();
            7、设置传递数据的超时时间,ReadTimeout当网络不正常的时候起作用
 conn.setReadTimeout(5000);
             8、设置一般请求属性,参数是规定的写法,放的是开始位置和结束位置,它会自动给你计算出结果
         conn.setRequestProperty("Range", "bytes="+start+"-"+end);
             9、然后就是一个读的操作,首先需要判断局部请求是否反应成功,状态码是206
         if(conn.getResponseCode()==206){                //这里需要用到数据定位的方法seekraf.seek(start);//获取输入流InputStream is=conn.getInputStream();byte bytes[]=new byte[1024];int len=0;while((len-is.read(bytes,0,bytes.length))!=-1){raf.write(bytes,0,len);}raf.close();is.close();}
服务器代码

package com.bihua.test;import java.io.File;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class DownThread extends Thread{public int id;//线程idpublic URL url;//文件下载的路径public File file;//文件保存的路径public int singleThreadNum;//单个线程下载的数据量public DownThread(int id, URL url, File file, int singleThreadNum) {this.id = id;this.url = url;this.file = file;this.singleThreadNum = singleThreadNum;}@Overridepublic void run() {try {RandomAccessFile raf=new RandomAccessFile(file, "rwd");//分别计算每个下载的开始位置和结束位置int start=id*singleThreadNum;int end=(id+1)*singleThreadNum;//通过传过来的URL获取下载的链接HttpURLConnection conn=(HttpURLConnection) url.openConnection();//设置下载超时值,是传递数据的超时时间。当网络不正常时,ReadTimeout才真正的起作用conn.setReadTimeout(5000);//设置一般请求属性conn.setRequestProperty("Range", "bytes="+start+"-"+end);//局部请求  状态码为206if(conn.getResponseCode()==206){raf.seek(start);//获取输入流InputStream is=conn.getInputStream();byte bytes[]=new byte[1024];int len=0;while((len-is.read(bytes,0,bytes.length))!=-1){raf.write(bytes,0,len);}raf.close();is.close();}} catch (Exception e) {e.printStackTrace();}}
}
客户端:
package com.zking.test;import java.io.File;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class TestDowm {public static void main(String[] args) {//设置线程数int threadNum=50;                //路径放你要从哪个网站进行下载,放地址栏的路径               String path="路径";//httpUrlConnectiontry {//获取下载地址URL url=new URL(path);//通过下载地址打开连接HttpURLConnection conn=(HttpURLConnection) url.openConnection();//设定请求方式conn.setRequestMethod("GET");//判断响应码是否为200  只有200的时候才会进入这个网页if(conn.getResponseCode()==200){//获取服务器中文件的大小int length=conn.getContentLength();//保存的文件路径File f=new File(路径);//对随机的文件进行读写RandomAccessFile raf=new RandomAccessFile(f, "rw");//设置下载文件大小raf.seek(length);raf.close();//每个线程下载的数据量int singleThreadNum=length%threadNum==0?length/threadNum:length/threadNum+1;for (int i = 0; i < threadNum; i++) {new DownThread(i, url, f, singleThreadNum).start();}}else{System.out.println("网页错误");}} catch (Exception e) {e.printStackTrace();}}}

多线程的下载就整理到这里,如有不懂的地方可以进行评论或者私信我,欢迎同道之人指点一二!


   






阅读全文
0 0
原创粉丝点击