java 多线程下载网络图片、视频等


一、使用准备

创建一个StartThread 类继承 Runnable 实现多线程


import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class StartThread implements Runnable {
    private String urlLocation;

    private String filePath;

    private long start;

    private long end;

    public StartThread(String urlLocation, String filePath, long start, long end) {
        this.urlLocation = urlLocation;
        this.filePath = filePath;
        this.start = start;
        this.end = end;
    }

    @Override
    public void run() {
        try {

            System.out.println("进入多线程方法");

            HttpURLConnection conn = getHttp();

            conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
            System.out.println("图片名称-->" + filePath);

            File file = new File(filePath);
            RandomAccessFile out = null;

            if (file != null) {
                out = new RandomAccessFile(file, "rwd");
            }

            out.seek(start);
            InputStream in = conn.getInputStream();

            byte[] b = new byte[1024];
            int len = 0;
            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
            in.close();
            out.close();


        } catch (Exception e) {
            System.out.println("download fail");
            e.printStackTrace();

        }

    }

    /**
     * 创建连接
     *
     * @return
     */
    public HttpURLConnection getHttp() {
        URL url = null;
        HttpURLConnection conn = null;
        try {

            if (urlLocation != null) {
                url = new URL(urlLocation);
            }
            conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(5000);
            conn.setRequestMethod("GET");
        } catch (Exception e) {
            System.out.println("getHttp error");
        }
        return conn;
    }

}

二、一个文件实现多线程下载

例如:下载一个视频的时候,文件很大却又想下载快些就可以使用多线程进行下载。多线程的方式把一个视频查分成多个视频进行下载,加快视频的下载速度。


import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class CreateThread {
    /**
     * 实现多线程 方法
     * @param urlLocation //网络图片地址    //  一个图片使用
     * @param filePath
     * @param poolLength
     * @throws IOException
     */
    public void getFileWithThreadPool(String urlLocation,String filePath, int poolLength) throws IOException{

        ExecutorService threadPool = Executors.newFixedThreadPool(poolLength);
        /**
         * 下载一个文件多线程下载(一个文件很大 可以由多个线程一起下载)
         */
        long len = getContentLength(urlLocation);
        System.out.println("一个文件大小--》"+len+"--线程数--》"+poolLength);

        for(int i=0;i<poolLength;i++){

            long start=i*len/poolLength;
            long end = (i+1)*len/poolLength-1;

            System.out.println("start-->"+start+"--end-->"+end);
            if(i==poolLength-1){
                end =len;
                System.out.println("len 赋值");
            }

            //创建多个线程
            StartThread download=new StartThread(urlLocation, filePath, start,end);
            threadPool.execute(download);

        }

        //让线程执行完自动关闭
        threadPool.shutdown();
        System.err.println("分配线程 任务结束");
    }


    /**
     * 获取文件的大小 (单位 byte)
     * @param urlLocation
     * @return
     * @throws IOException
     */
    private static long getContentLength(String urlLocation) throws IOException{
        URL url = null;
        if (urlLocation != null)
        {
            url = new URL(urlLocation);
        }
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(5000);
        conn.setRequestMethod("GET");
        long len = conn.getContentLength();

        return len;
    }



    public static void main(String[] args) {
        try {

            //一个文件  多线程下载
//            String url = "http://img.tupianzj.com/uploads/allimg/140716/3-140G61501440-L.jpg";
            String url = "https://resource.meihua.info/2SxYJ5jka40dYgykSYASyV3Rrik=/lkbiIFctwfhJpPG2epYX_iOTOSS6";

            CreateThread createThread = new CreateThread();
            // 网络文件url --- 存放路径 --- 创建的线程数
            createThread.getFileWithThreadPool(url, "D:/usr/share/", 3);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


三、多个文件实现多线程

例如:实现多个文件同时下载,通过爬虫的方式,或者其他渠道获得到的图片、视频路径(多个),如果成千上百个图片、视频还好你可以等一会,但是上万个,就算一个文件一秒,你也不想等把,如果是视频呢,所以就总结了一下,使用多线程的方式,同时下载多个文件。既加快速度页,又节省时间


import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//同时下载多个文件
public class MoreFileCreateThread {
    /**
     * 实现多线程 方法
     *
     * @param urlLocation //网络图片地址    多个图片用逗号(,)隔开 使用 同时下载多个文件
     * @param filePath
     * @param poolLength
     * @throws IOException
     */
    public void getFileWithThreadPool(String urlLocation, String filePath, int poolLength) throws IOException {

        ExecutorService threadPool = Executors.newFixedThreadPool(poolLength);


        /**
         * 同时下载多个文件
         */
        String[] arrayStrings = urlLocation.split(",");
        poolLength = arrayStrings.length;

        System.out.println("线程数" + poolLength);

        //也可以写一个固定的线程数  一个线程里面执行一份部分下载

        for (int a = 0; a < arrayStrings.length; a++) {
            System.out.println(a + "长度" + arrayStrings[a]);
            long len = getContentLength(arrayStrings[a]);

            StartThread download = new StartThread(arrayStrings[a], filePath + a + ".jpg", 0, len);
            threadPool.execute(download);

        }

        //让线程执行完自动关闭
        threadPool.shutdown();
        System.err.println("分配线程 任务结束");
    }


    /**
     * 获取文件的大小 (单位 byte)
     *
     * @param urlLocation
     * @return
     * @throws IOException
     */
    private static long getContentLength(String urlLocation) throws IOException {
        URL url = null;
        if (urlLocation != null) {
            url = new URL(urlLocation);
        }
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(5000);
        conn.setRequestMethod("GET");
        long len = conn.getContentLength();

        return len;
    }


    public static void main(String[] args) {
        try {

            //多个文件多线程下载  用逗号(,) 隔开
            String url = "http://img.tupianzj.com/uploads/allimg/140716/3-140G61501440-L.jpg, http://img.tupianzj.com/uploads/allimg/140418/3-14041Q43F40-L.jpg, http://img.tupianzj.com/uploads/allimg/140319/4-1403191055450-L.jpg, http://img.tupianzj.com/uploads/allimg/131120/3-1311200954320-L.jpg, http://img.tupianzj.com/uploads/allimg/130802/4-130P21036010-L.jpg, http://img.tupianzj.com/uploads/allimg/170107/9-1F10H004310-L.jpg, http://img.tupianzj.com/uploads/allimg/180523/9-1P5231000080-L.jpg, http://img.tupianzj.com/uploads/allimg/170309/9-1F3092145190-L.jpg, http://img.tupianzj.com/uploads/allimg/161107/9-16110H205210-L.jpg, http://img.tupianzj.com/uploads/allimg/170107/9-1F10H004310-L.jpg, http://img.tupianzj.com/uploads/allimg/140604/3-1406041414480-L.jpg, http://img.tupianzj.com/uploads/allimg/171017/9-1G01G15T00-L.jpg, http://img.tupianzj.com/uploads/allimg/170805/9-1FP51IA80-L.jpg, http://img.tupianzj.com/uploads/allimg/180331/9-1P3311131060-L.jpg, http://img.tupianzj.com/uploads/allimg/140102/3-1401021142510-L.jpg, http://img.tupianzj.com/uploads/allimg/161121/9-1611212039430-L.jpg, http://img.tupianzj.com/uploads/allimg/150317/7-15031G511460-L.jpg, http://img.tupianzj.com/uploads/allimg/180202/9-1P2021AS60-L.jpg, http://img.tupianzj.com/uploads/allimg/180202/9-1P2021A5070-L.jpg";

            MoreFileCreateThread createThread = new MoreFileCreateThread();
            // 网络文件url --- 存放路径 --- 创建的线程数
            createThread.getFileWithThreadPool(url, "D:/临时/threadimg/", 3);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}


四、封装使用示例

接富文本提取资源上传
在这里插入图片描述

富文本提取资源

    //将网络链接下载到本地,输出新的文件名
    @Transactional
    public String urlFileThread(String url, int poolLength) throws IOException {

        String fileName = (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date()) + "_" + RandomUtil.randomInt(10000);
        String name = url.substring(url.lastIndexOf("/") + 1);
        int len = name.lastIndexOf(".");
        if (len <= 0) {
            throw new ServiceException("文件类型有误,请确认!");
        } else {
            fileName = fileName + name.substring(len);
        }
        CreateThread createThread = new CreateThread();
        // 网络文件url --- 存放路径 --- 创建的线程数
        createThread.getFileWithThreadPool(url, filePath + fileName, poolLength);

        return fileName;
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值