zoukankan      html  css  js  c++  java
  • java多线程下载文件和断点下载

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    import javax.print.attribute.standard.Finishings;
    
    public class MultiDownload {
    
        static int ThreadCount = 3;       //代表3个进程
        static int finishedThread = 0;   //记录文件下完的数字
        //确定下载地址
        static String path = "http://192.168.13.13:8080/QQPlayer.exe";
        public static void main(String[] args) {
            
            //发送get请求,请求这个地址的资源
            try {
                URL url = new URL(path);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                
                if(conn.getResponseCode() == 200){
                    //拿到所请求资源文件的长度
                    int length = conn.getContentLength();
                    
                    File file = new File("QQPlayer.exe");
                    //生成临时文件
                    RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                    //设置临时文件的大小
                    raf.setLength(length);
                    raf.close();
                    //计算出每个线程应该下载多少字节
                    int size = length / ThreadCount;
                    
                    for (int i = 0; i < ThreadCount; i++) {
                        //计算线程下载的开始位置和结束位置
                        int startIndex = i * size;
                        int endIndex = (i + 1) * size - 1;
                        //如果是最后一个线程,那么结束位置写死
                        if(i == ThreadCount - 1){
                            endIndex = length - 1;
                        }
    //                    System.out.println("线程" + i + "的下载区间是:" + startIndex + "---" + endIndex);
                        new DownLoadThread(startIndex, endIndex, i).start();
                    }
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        
    }
    class DownLoadThread extends Thread{
        int startIndex;
        int endIndex;
        int threadId;
        
        public DownLoadThread(int startIndex, int endIndex, int threadId) {
            super();
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.threadId = threadId;
        }
    
        @Override
        public void run() {
            //再次发送http请求,下载原文件
            try {
                File progressFile = new File(threadId + ".txt");
                //判断进度临时文件是否存在
                if(progressFile.exists()){
                    FileInputStream fis = new FileInputStream(progressFile);
                    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
                    //从进度临时文件中读取出上一次下载的总进度,然后与原本的开始位置相加,得到新的开始位置
                    startIndex += Integer.parseInt(br.readLine());
                    fis.close();
                }
                System.out.println("线程" + threadId + "的下载区间是:" + startIndex + "---" + endIndex);
                HttpURLConnection conn;
                URL url = new URL(MultiDownload.path);
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                //设置本次http请求所请求的数据的区间
                conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
                
                //请求部分数据,相应码是206
                if(conn.getResponseCode() == 206){
                    //流里此时只有1/3原文件的数据
                    InputStream is = conn.getInputStream();
                    byte[] b = new byte[1024];
                    int len = 0;
                    int total = 0;
                    //拿到临时文件的输出流
                    File file = new File("QQPlayer.exe");
                    RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                    //把文件的写入位置移动至startIndex
                    raf.seek(startIndex);
                    while((len = is.read(b)) != -1){
                        //每次读取流里数据之后,同步把数据写入临时文件
                        raf.write(b, 0, len);
                        total += len;
    //                    System.out.println("线程" + threadId + "下载了" + total);
                        
                        //生成一个专门用来记录下载进度的临时文件
                        RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");
                        //每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中
                        progressRaf.write((total + "").getBytes());
                        progressRaf.close();
                    }
                    System.out.println("线程" + threadId + "下载完毕-------------------小志参上!");
                    raf.close();
                    
                    //把记录进程的文件删除    必须3个进程全部都下载完成后才可以删除
                    MultiDownload.finishedThread++;
                    synchronized (MultiDownload.path) {  //有线程安全问题,静态变量为唯一的
                        if(MultiDownload.finishedThread == MultiDownload.ThreadCount){
                            for (int i = 0; i < MultiDownload.ThreadCount; i++) {
                                File f = new File(i + ".txt");
                                f.delete();
                            }
                            MultiDownload.finishedThread = 0;
                        }
                    }
                    
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    JS各种各样的拖动效果
    GridView实现自动编号
    通用海量数据库翻页
    设置首页和添加到收藏夹的JavaScript代码
    JavaScript弹出窗口总结
    JavaScript获取窗口的高度和宽度
    精妙SQL语句
    Javascript 操作select控件大全(新增、修改、删除、选中、清空、判断存在等)
    GridView数据导入Excel
    网站采集
  • 原文地址:https://www.cnblogs.com/mabiao008/p/8118630.html
Copyright © 2011-2022 走看看