Java中使用RandomAccessFile类实现多线程下载
2014-07-18 15:01
429 查看
多线程下载文件的注意点主要有:
1、确定每个线程下载的文件大小,用这种方法计算:
先获取整个文件的大小length,然后除以线程个数count得到每个线程下载的块大小为blockSize = length / count,每个线程的起始下载点为:startPos = blockSize * i,结束下载点为:endPos = blockSize * (i + 1) - 1,其中最后一个线程下载的结束点应该为文件末尾
2、随机访问文件RandomAccessFile类的使用方法,该类的实例化需要两个参数,第一个可以使一个文件File类,也可以是文件的path,String类,第二个参数代表文件写入的模式,可以为"r","rw","rws","rwd"之一
3、在每个线程中写文件的时候都需要实例化一个RandomAccessFile的实例,而不能重复使用同一个RandomAccessFile
4、在设置请求参数时,获取服务器的响应码会有所不同,如果请求的是一整个资源,则请求成功的响应码是200,若请求的是某个资源的部分时,请求成功返回的响应码是206,这一点需要注意,另外,在每个线程中下载一个文件的不同部分时,需要设置请求的头字段:conn.setRequestProperty("Range", "bytes=12345-13456");设置该头字段代表请求服务器资源的12345到13456这部分的内容
另外,在每个线程下载之前,需要将RandomAccessFile的实例的指针指向下载的开始点,使用如下方法:
raf.seek(startPos); 其中raf为RandomAccessFile类的对象,startPos为下载的开始点
1、确定每个线程下载的文件大小,用这种方法计算:
先获取整个文件的大小length,然后除以线程个数count得到每个线程下载的块大小为blockSize = length / count,每个线程的起始下载点为:startPos = blockSize * i,结束下载点为:endPos = blockSize * (i + 1) - 1,其中最后一个线程下载的结束点应该为文件末尾
2、随机访问文件RandomAccessFile类的使用方法,该类的实例化需要两个参数,第一个可以使一个文件File类,也可以是文件的path,String类,第二个参数代表文件写入的模式,可以为"r","rw","rws","rwd"之一
3、在每个线程中写文件的时候都需要实例化一个RandomAccessFile的实例,而不能重复使用同一个RandomAccessFile
4、在设置请求参数时,获取服务器的响应码会有所不同,如果请求的是一整个资源,则请求成功的响应码是200,若请求的是某个资源的部分时,请求成功返回的响应码是206,这一点需要注意,另外,在每个线程中下载一个文件的不同部分时,需要设置请求的头字段:conn.setRequestProperty("Range", "bytes=12345-13456");设置该头字段代表请求服务器资源的12345到13456这部分的内容
另外,在每个线程下载之前,需要将RandomAccessFile的实例的指针指向下载的开始点,使用如下方法:
raf.seek(startPos); 其中raf为RandomAccessFile类的对象,startPos为下载的开始点
import java.io.File; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class Test { /** * 文件下载的路径 */ private static final String PATH = "http://localhost:8080/test.exe"; /** * 下载的线程个数 */ private static final int COUNT = 3; /** * 创建一个文件,将远程文件写入该文件 */ private File f = new File("C:\\Users\\Administrator\\Desktop\\test.exe"); public void download() throws Exception{ URL url = new URL(PATH); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //使用get请求 conn.setRequestMethod("GET"); //设置连接超时时间为5秒 conn.setConnectTimeout(5000); //得到服务器返回的响应码 int code = conn.getResponseCode(); //响应码为200,代表请求资源成功(前提是请求整个资源,而不是资源的某一部分) if(code == 200){ //得到文件的总大小 int length = conn.getContentLength(); //新建一个随机访问的文件 RandomAccessFile raf = new RandomAccessFile(f, "rw"); //第一个参数为文件类型,第二个参数为模式,可以为"r","rw","rws","rwd" raf = new RandomAccessFile(f, "rw"); //设置随机文件的大小为服务器端文件的大小 raf.setLength(length); System.out.println("文件总大小为:" + length); //计算每个线程下载的块的大小 int blockSize = length / COUNT; for(int i = 0; i < COUNT; i++){ //每个线程的起始下载点 int startPos = blockSize * i; //每个线程的结束下载点 int endPos = blockSize * (i + 1) - 1; //如果是最后一条线程,将其下载的终止点设为文件的终点 if(i == COUNT){ endPos = length; } System.out.println("线程" + i + "下载的部分为:" + startPos +"---" + endPos); //开启线程分别下载不同的部分 new DownThread(i, startPos, endPos).start(); } } } /** * 下载文件的线程 * @author Administrator * */ class DownThread extends Thread{ //线程ID private int threadId; //线程下载的起始点 private int startPos; //线程下载的结束点 private int endPos; public DownThread(int threadId, int startPos, int endPos) { this.threadId = threadId; this.startPos = startPos; this.endPos = endPos; } @Override public void run(){ try { URL url = new URL(PATH); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); //设置头部的参数,表示请求服务器资源的某一部分 conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); //设置了上面的头信息后,响应码为206代表请求资源成功,而不再是200 int code = conn.getResponseCode(); if(code == 206){ InputStream is = conn.getInputStream(); int hasRead = 0; byte[] buf = new byte[1024]; //这里要注意新创建一个RandomAccessFile对象,而不能重复使用download方法中创建的 RandomAccessFile raf = new RandomAccessFile(f, "rw"); //将写文件的指针指向下载的起始点 raf.seek(startPos); while((hasRead = is.read(buf)) > 0) { raf.write(buf, 0, hasRead); } is.close(); System.out.println("线程" + threadId + "下载完毕..."); } } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { try { new Test().download(); } catch (Exception e) { e.printStackTrace(); } } }
相关文章推荐
- 使用java实现http多线程断点下载文件(二)
- 使用Java实现多线程下载断点续传功能案例
- Java使用HttpUrlConnection实现多线程断点下载
- Java使用HttpUrlConnection实现多线程断点下载
- Java中使用多线程实现文件上传和下载
- 使用java实现http多线程断点下载文件(一)
- JAVA中使用FTPClient实现文件上传下载
- JAVA多线程:什么时候使用哪种实现方式
- Java多线程实现下载功能
- JAVA多线程:什么时候使用哪种实现方式
- 使用 java 开源资源实现通用可靠的下载组件
- Java使用Http实现网络图片的下载
- Java中如何使用组件实现文件上传下载
- JAVA中使用FTPClient实现文件上传下载(键人岐)
- JAVA多线程实现和应用总结:如何使用有返回值的多线程
- Java实现多线程断点下载
- Java 使用FTPClient实现上传下载
- jsp里使用java excel api实现文件下载
- JAVA中使用FTPClient实现文件上传下载
- Web项目中使用java Struts2实现Zip、xml文件的动态创建和下载(Zip文件中动态存在多个xml文件)