Java下载文件有没有好的工具类

通过原生写下载代码有点长,而且无法获得下载进度,如下图:
有没有现成的第三方库或者utils工具包之类的…精简代码行数同时可以取得下载中的进度。

img

java nio + java.net.URL

    public static void downloadFile(String fileUrl, String savePath) throws IOException {
        URL url = new URL(fileUrl);
        try (InputStream in = new BufferedInputStream(url.openStream());
             FileOutputStream fileOutputStream = new FileOutputStream(savePath)) {
            byte[] dataBuffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
        }
    }

    public static void downloadFileWithJavaNIO(String fileUrl, String savePath) throws IOException {
        URL url = new URL(fileUrl);
        try (InputStream in = url.openStream()) {
            Path outputPath = Path.of(savePath);
            Files.copy(in, outputPath, StandardCopyOption.REPLACE_EXISTING);
        }
    }

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7809051
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:Java面试之重量级锁、轻量级锁(锁、分布式锁、锁升级)实现原理
  • 除此之外, 这篇博客: 【02】Java进阶:06-综合练习、学生信息管理系统中的 3.4 工具类Utils类 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    public class Utils {
    
        // 定义一个静态的id变量,用来给学生对象的id赋值
        public static int id ;// 100个对象 id=100 程序停止再启动
    
        static {
            id = 0;// 以后可以读取文件中记录的id值,赋为初始值
        }
    
    
        // 根据生日计算年龄的方法
        public static int birthdayToAge(String birthday){
            // 思路:
            // 1. 获取当前日期对象
            Date nowDate = new Date();
    
            // 2. 创建日期格式化对象,指定日期格式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
            // 3. 调用parse()解析方法对字符串生日解析为Date类型的生日
            Date birthdayDate = null;
            try {
                birthdayDate = sdf.parse(birthday);
            } catch (ParseException e) {
                e.printStackTrace();
            }
    
            // 4.比较出生日期是否在当前日期之后,如果是,直接返回 -1;
            if (birthdayDate.after(nowDate)) {
                return -1;
            }
            // 5.获取当前时间的日历对象
            Calendar cal = Calendar.getInstance();
    
            // 6.获取当前时间的年,月,日
            int nowYear = cal.get(Calendar.YEAR);
            int nowMonth = cal.get(Calendar.MONTH);
            int nowDay = cal.get(Calendar.DAY_OF_MONTH);
    
            // 7.通过日历对象调用setTime(Date date)方法,设置日历对象的时间为出生日期的时间
            cal.setTime(birthdayDate);
    
            // 8.通过设置之后的日历对象获取生日的年,月,日
            int birthdayYear = cal.get(Calendar.YEAR);
            int birthdayMonth = cal.get(Calendar.MONTH);
            int birthdayDay = cal.get(Calendar.DAY_OF_MONTH);
    
            // 9.使用当前时间的年 - 生日的年 得到一个初步的年龄
            int age = nowYear - birthdayYear;
    
            // 10.如果当前时间的月 小于 生日的月份,那么初步年龄-1
            if (nowMonth < birthdayMonth){
                age--;
            }
    
            // 11.如果当前时间的月 等于生日的月份,但当前时间的日 小于 生日的日,那么初步年龄-1
            if (nowMonth == birthdayMonth){
                if (nowDay < birthdayDay){
                    age--;
                }
            }
            // 10.直接返回年龄
            return age;
        }
    
        // 打印Person对象
        public static void printPerson(Person p){
            System.out.println(p.getId()+"\t\t"+p.getName()+
                    "\t\t"+p.getSex()+"\t\t"+p.getBirthday()+
                    "\t\t"+p.getAge()+"\t\t"+p.show());
        }
    
        // 打印集合所有元素
        public static void printArrayList(ArrayList list){
            System.out.println("**************************************************************************");
            System.out.println("编号\t\t姓名\t\t性别\t\t生日\t\t\t\t年龄\t\t描述");
            // 循环遍历集合
            for (int i = 0; i < list.size(); i++) {
                // 获取集合元素
                Person p = (Person) list.get(i);
                // 打印对象
                printPerson(p);
            }
            System.out.println("**************************************************************************");
        }
    }
    
  • 以下回答来自chatgpt:

    对于Java下载文件并提供下载进度的功能,可以使用Apache HttpClient和Apache Commons IO这两个库来实现。以下是一个使用这两个库的例子:

    首先,需要在项目的依赖中添加Apache HttpClient和Apache Commons IO的相关库。可以在pom.xml文件中添加如下依赖:

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
    

    接下来,可以使用下面的代码来下载文件并获取下载进度:

    import org.apache.commons.io.FileUtils;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    import java.io.File;
    import java.io.IOException;
    
    public class FileDownloader {
        public static void main(String[] args) {
            String fileUrl = "https://example.com/file.pdf"; // 要下载的文件的URL
            String saveDirectory = "/path/to/save/directory"; // 下载文件保存的目录
    
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(fileUrl);
    
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                long fileSize = response.getEntity().getContentLength();
                FileUtils.copyInputStreamToFile(response.getEntity().getContent(),
                        new File(saveDirectory, getFileName(fileUrl)),
                        4096,
                        fileSize,
                        new FileUtils.ProgressListener() {
                            private long totalBytesRead = 0;
    
                            @Override
                            public void progress(long bytesRead, long contentLength, int items) {
                                totalBytesRead += bytesRead;
                                System.out.println("已下载:" + totalBytesRead + " / " + fileSize);
                            }
                        });
    
                System.out.println("文件下载完成");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private static String getFileName(String fileUrl) {
            return fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
        }
    }
    

    这段代码使用了FileUtils.copyInputStreamToFile方法来实现文件下载,并利用ProgressListener监听下载进度。每次读取指定长度的字节时,会调用ProgressListener的progress方法来打印下载进度。

    希望这个解决方案能对您有所帮助。如果有任何问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^