• Java多线程下载文件


    package com.test.download;
     
    import java.io.File;
    import java.io.InputStream;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.URL;
     
    /*
     * 多线程下载
     */
    public class MulThreadDownload {
     
        public static void main(String[] args) throws Exception {
            String path = "http://pic.4j4j.cn/upload/pic/20130909/681ebf9d64.jpg";
            new MulThreadDownload().download(path,3);
        }
         
        public void download (String path,int threadsize) throws Exception{
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("GET");
            if(conn.getResponseCode() == 200){
                //获取网络文件长度
                int length = conn.getContentLength();  
                //新建本地文件保存下载数据
                File file = new File(getFilename(path));
                //计算每条线程负责下载的数据量
                int block = length%threadsize==0 ? length/threadsize : length/threadsize+1;
                //开启指定数目的线程同时下载
                for(int threadid = 0; threadid < threadsize; threadid++){
                    new DownloadThread(threadid,block,url,file).start();
                }
            }else{
                System.out.println("下载失败!");
            }
        }
         
        private class DownloadThread extends Thread{
            private int threadid;   //线程编号
            private int block;      //下载块大小
            private URL url;        //下载链接
            private File file;      //下载数据保存文件
            public DownloadThread(int threadid, int block, URL url, File file) {
                this.threadid = threadid;
                this.block = block;
                this.url = url;
                this.file = file;
            }
     
            public void run() {
                int start = threadid * block;       //本线程下载数据写入文件开始位置
                int end = (threadid+1) * block - 1; //本线程下载数据写入文件结束位置
                try {
                    //创建一个随机访问文件流对象
                    RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
                    //文件指针偏移至正确写入位置
                    accessFile.seek(start);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(5000);
                    conn.setRequestMethod("GET");
                    //设置请求数据的范围
                    conn.setRequestProperty("Range", "bytes="+start+"-"+end);
                    if(conn.getResponseCode() == 206){//状态码206:(部分内容) 服务器成功处理了部分 GET 请求
                        InputStream inStream = conn.getInputStream();
                        byte[] buffer = new byte[1024];
                        int len = 0;
                        while((len = inStream.read(buffer)) != -1){
                            accessFile.write(buffer, 0, len);
                        }
                        accessFile.close();
                        inStream.close();
                    }
                    System.out.println("第"+(threadid+1)+"部分下载完成");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
     
        private String getFilename(String path) {
            return path.substring(path.lastIndexOf("/")+1);
        }
    }
  • 相关阅读:
    SQL Server 2008 R2的发布订阅配置实践
    【SQL Server高可用性】数据库复制:SQL Server 2008R2中数据库复制
    sql server几种读写分离方案的比较
    SQL Server 数据库文件管理
    SQL Server 表和索引存储结构
    SQL Server 查询优化 索引的结构与分类
    C#延迟初始化Lazy<T>
    【转】编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试
    【转】编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本
    【转】编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码
  • 原文地址:https://www.cnblogs.com/sandea/p/4612319.html
Copyright © 2020-2023  润新知