欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java – How to download a file from the Internet  

程序员文章站 2022-06-10 09:40:07
...
参考链接:https://www.mkyong.com/java/java-how-to-download-a-file-from-the-internet/

1、Apache Commons IO
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

 String fromFile = "ftp://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest";
        String toFile = "F:\\arin.txt";
        try {

            // connectionTimeout, readTimeout = 10 seconds
            FileUtils.copyURLToFile(new URL(fromFile), new File(toFile), 10000, 10000);

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


2、Java NIO
String fromFile = "https://download-cf.jetbrains.com/idea/ideaIU-2018.1.6.win.zip";
        String toFile = "F:\\IDEA\\ideaIU-2018.1.6.win.zip";       

        try {

            URL website = new URL(fromFile);
            ReadableByteChannel rbc = Channels.newChannel(website.openStream());
            FileOutputStream fos = new FileOutputStream(toFile);
            fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
            fos.close();
            rbc.close();
            System.out.println("---------success----------------");
        } catch (IOException e) {
            e.printStackTrace();
        }



    static final String FILE_URL  = "https://download-cf.jetbrains.com/idea/ideaIU-2018.1.6.exe";

    static final String FILE_NAME = "F:\\IDEA\\ideaIU-2018.1.6.exe";

    public static void main(String[] args) throws Exception {

        javaIO();

    }

    static void javaIO() {
        try (BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream());
                FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)) {
            byte dataBuffer[] = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                System.out.println("read >" + bytesRead);
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
        } catch (IOException e) {
            // handle exception
        }
    }


3、多线程下载文件
package net.liuzidong.download;

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

/**
 * 多线程下载文件
 */
public class DownloadUtil {

    // 定义成员变量
    private String           path;             // 远程资源路径
    private String           targetPath; // 本地存储路径
    private DownFileThread[] threads;       // 线程list
    private int              threadNum;   // 线程数量
    private long             length;         // 下载的文件大小

    // 构造初始化
    public DownloadUtil(String path, String targetPath, int threadNum) {
        super();
        this.path = path;
        this.targetPath = targetPath;
        this.threads = new DownFileThread[threadNum];
        this.threadNum = threadNum;
    }

    // 多线程下载文件资源
    public void download() {
        URL url;
        try {
            url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
            conn.setRequestMethod("GET");
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("accept", "*/*");

            // 获取远程文件的大小
            length = conn.getContentLength();
            conn.disconnect();

            // 设置本地文件大小
            RandomAccessFile targetFile = new RandomAccessFile(targetPath, "rw");
            targetFile.setLength(length);

            // 每个线程下载大小
            long avgPart = length / threadNum + 1;
            // 下载文件
            for (int i = 0; i < threadNum; i++) {
                long startPos = avgPart * i;
                RandomAccessFile targetTmp = new RandomAccessFile(targetPath, "rw");
                targetTmp.seek(startPos); // 分段下载
                threads[i] = new DownFileThread(startPos, targetTmp, avgPart);
                threads[i].start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 监控下载进度
    public double getDownRate() {
        int currentSize = 0;
        for (int i = 0; i < threadNum; i++) {
            currentSize += threads[i].length;
        }
        return currentSize * 1.0 / length;
    }

    // 定义线程类
    class DownFileThread extends Thread {

        private long             startPos;
        private RandomAccessFile raf;
        private long             size;
        private long             length;

        public DownFileThread(long startPos, RandomAccessFile raf, long size) {
            super();
            this.startPos = startPos;
            this.raf = raf;
            this.size = size;
        }

        public void run() {
            URL url;
            try {
                url = new URL(path);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
                conn.setRequestMethod("GET");
                conn.setRequestProperty("connection", "keep-alive");
                conn.setRequestProperty("accept", "*/*");

                InputStream in = conn.getInputStream();
                in.skip(this.startPos);
                byte[] buf = new byte[1024];
                int hasRead = 0;
                while (length < size && (hasRead = in.read(buf)) != -1) {
                    raf.write(buf, 0, hasRead);
                    length += hasRead;
                }
                raf.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 测试
    public static void main(String[] args) {
        String path = "http://ftp.jaist.ac.jp/pub/eclipse/technology/epp/downloads/release/photon/R/eclipse-jee-photon-R-win32-x86_64.zip";
        String targetPath = "F:\\download\\eclipse\\eclipse-jee-photon-R-win32-x86_64.zip";
        final DownloadUtil download = new DownloadUtil(path, targetPath, 3);
        download.download();
        System.out.println("开始下载...");
        // 主线程负责下载文件,在启动一个线程负责监控下载的进度
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (download.getDownRate() < 1) {
                    try {
                        Thread.sleep(2000); // 200毫秒扫描一次
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("下载完成...");
            }

        }).start();
    }
}