java中多线程下载
2015-07-03 18:01
543 查看
package com.download; import java.io.File; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class MutileThreadDown { private static int blockCount=3; private static int blockSize; public static void main(String[] args) throws Exception{ String path="http://localhost:8080/Web025Server/media/bootstrap.avi"; URL url=new URL(path); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); int responseCode=conn.getResponseCode(); if(responseCode==200){ int size=conn.getContentLength(); System.out.println("服务器端的长度"+size); blockSize=size/blockCount; //创建一个跟服务器端大小相同的空白文件 File file=new File("aa.avi"); RandomAccessFile raf=new RandomAccessFile(file,"rw"); raf.setLength(size);//设置文件的的大小 //2.开启若干个子线程,分别下载资源 for(int i=1;i<=blockCount;i++){ int startIndex=(i-1)*blockSize+0; int endIndex=i*blockSize-1; if(i==blockCount){ endIndex=size-1; } new DownLoadThread(startIndex, endIndex, i, path).start();; System.out.println("开启线程"+i+"开始的位置"+startIndex+"结束的位置是"+endIndex); } } conn.disconnect(); } //定义一个线程的内部类 private static class DownLoadThread extends Thread{ private int startIndex; private int endIndex; private int threadi; private String path; public DownLoadThread(int startIndex, int endIndex, int threadi, String path) { super(); this.startIndex = startIndex; this.endIndex = endIndex; this.threadi = threadi; this.path = path; } @Override public void run() { try { String path="http://localhost:8080/Web025Server/media/bootstrap.avi"; URL url=new URL(path); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); int responseCode=conn.getResponseCode(); System.out.println("服务器的响应码"+responseCode); //创建一个跟服务器端大小相同的空白文件 File file=new File("aa.avi"); RandomAccessFile raf=new RandomAccessFile(file,"rw"); InputStream in=conn.getInputStream(); raf.seek(startIndex);//从哪个位置开始写文件 int len=-1; byte[] bytes=new byte[1024]; while((len=in.read(bytes))!=-1){ raf.write(bytes, 0, len); } in.close(); raf.close(); } catch (Exception e) { e.printStackTrace(); } } } }下面我再贴一下更新后的代码吧,这个可以实现短点下载,关闭程序重新开启后可以继续下载
package com.download; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class MutileThreadDown { private static int blockCount=3;//定义需要开启线程的个数 private static int blockSize; private static int runningThreadCount;//正在运行的线程的数量 public static void main(String[] args) throws Exception{ String path="http://localhost:8080/Web025Server/media/bootstrap.avi"; URL url=new URL(path); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); int responseCode=conn.getResponseCode(); if(responseCode==200){ int size=conn.getContentLength(); System.out.println("服务器端的长度"+size);//服务器端需要下载文件的大小 blockSize=size/blockCount; //创建一个跟服务器端大小相同的空白文件 File file=new File("aa.avi"); RandomAccessFile raf=new RandomAccessFile(file,"rw"); raf.setLength(size);//设置文件的的大小 //2.开启若干个子线程,分别下载资源 runningThreadCount=blockCount;//刚开始设定正在运行的线程数是线程的总数 for(int i=1;i<=blockCount;i++){ int startIndex=(i-1)*blockSize+0; int endIndex=i*blockSize-1; if(i==blockCount){ endIndex=size-1;//最后一个线程需要下载剩下的 } new DownLoadThread(startIndex, endIndex, i, path).start();; System.out.println("开启线程"+i+"开始的位置"+startIndex+"结束的位置是"+endIndex); } } conn.disconnect(); } //定义一个线程的内部类 private static class DownLoadThread extends Thread{ private int startIndex; private int endIndex; private int threadi; private String path; public DownLoadThread(int startIndex, int endIndex, int threadi, String path) { super(); this.startIndex = startIndex; this.endIndex = endIndex; this.threadi = threadi; this.path = path; } @Override public void run() { try { //获取当前下载总文件的大小 int total=0; File filepos=new File(threadi+".txt");//建立一个txt文件记录下载的信息 String path="http://localhost:8080/Web025Server/media/bootstrap.avi"; URL url=new URL(path); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); //接着从上一次位置下载 if(filepos.exists()&&filepos.length()>0){//判断以前是否下载过 FileInputStream fis=new FileInputStream(filepos); BufferedReader br=new BufferedReader(new InputStreamReader(fis)); String lasttotalstr=br.readLine();//获取当前线程上一次下载的总大小 int lasttotal=Integer.valueOf(lasttotalstr); System.out.println("上一次下载的总大小"+lasttotal); startIndex+=lasttotal; total+=lasttotal; fis.close();//很重要 } conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); int responseCode=conn.getResponseCode(); System.out.println("服务器的响应码"+responseCode); //创建一个跟服务器端大小相同的空白文件 File file=new File("aa.avi"); RandomAccessFile raf=new RandomAccessFile(file,"rw"); InputStream in=conn.getInputStream(); raf.seek(startIndex);//从哪个位置开始写文件 int len=-1; byte[] bytes=new byte[1024*1024]; while((len=in.read(bytes))!=-1){ RandomAccessFile rf=new RandomAccessFile(filepos, "rwd"); raf.write(bytes, 0, len); total+=len; rf.write(String.valueOf(total).getBytes()); rf.close(); } in.close(); raf.close(); } catch (Exception e) { e.printStackTrace(); } finally{ synchronized (this) { runningThreadCount--; if(runningThreadCount==0){ System.out.println("所有线程下载完毕,可以删除txt记录文件了");//可能会出现线程安全问题 for(int i=1;i<=blockCount;i++){ File f=new File(i+".txt"); boolean b=f.delete(); System.out.println(b); } } } } } } }
本文出自 “Java大白的战地” 博客,请务必保留此出处http://8023java.blog.51cto.com/10117207/1670663
相关文章推荐
- 在Java中定义常量(Constant) ,简化代码
- Java基础编程:反射工具类
- 深入理解Java的接口和抽象类
- Java - What is Abstraction in Java
- java中重载与重写的区别
- JAVA实现图片裁剪
- JAVA对象属性复制
- 搭建和配置Spring与jdbc整合的环境
- Java NumberFormat 类
- Android Studio vs. Eclipse: What You Need To Know
- eclipse安装maven插件
- [转] Java快速教程
- Spring MVC 3.0 深入及对注解的详细讲解
- Oauth2.0 用Spring-security-oauth2 非常简单
- Spring Security 与 Oauth2 整合 步骤
- java垃圾回收机制(二)
- Java - What is Static and Dynamic binding
- Eclipse导出项目兼容androidstudio
- Caused by: java.lang.UnsatisfiedLinkError: Couldn't load BaiduMapSDK_v3_0_0 from loader dalvik.syste
- java 垃圾回收机制(一)