Java通过文件流和文件地址下载文件

news2024/12/23 23:42:15

在这里插入图片描述

通过文件流下载文件

如何使用 MultipartFile 进行文件上传、下载到本地,并返回保存路径呢:

import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileUtils {

    private static final String UPLOAD_DIR = "/path/to/upload/directory/"; // 修改为您的上传目录

    public static String saveFileAndGetPath(MultipartFile file) throws IOException {
        String originalFileName = file.getOriginalFilename();
        String fileName = generateFileName(originalFileName);
        String filePath = UPLOAD_DIR + fileName;

        try (InputStream inputStream = file.getInputStream();
             BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath))) {

            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }

        return filePath;
    }

    private static String generateFileName(String originalFileName) {
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 时间戳精确到秒
        int dotIndex = originalFileName.lastIndexOf(".");
        String extension = (dotIndex != -1) ? originalFileName.substring(dotIndex) : "";
        String fileNameWithoutExtension = (dotIndex != -1) ? originalFileName.substring(0, dotIndex) : originalFileName;

        return fileNameWithoutExtension + "_" + timestamp + extension;
    }
}

用于在 Spring Boot 应用中获取文件流,然后处理上传的文件,将文件保存到指定目录并返回保存的文件路径。下面对代码的各个部分进行简要介绍:

  1. 上传目录设置:在这个示例中,UPLOAD_DIR 常量用于定义上传文件的目录路径。您需要将其修改为您实际希望保存上传文件的路径。

  2. 保存文件并获取路径saveFileAndGetPath 方法接收一个 MultipartFile 对象,表示上传的文件。在该方法中,将上传的文件保存到指定的目录中,并返回保存后的文件路径。

  3. 生成文件名generateFileName 方法用于生成带时间戳的新文件名,以避免文件名冲突。它使用当前时间的时间戳(精确到秒)作为文件名的一部分,并保留原始文件名的扩展名。

  4. 上传逻辑:在 saveFileAndGetPath 方法中,使用 MultipartFile 对象的输入流来读取上传文件的内容,并通过输出流将内容写入指定的文件路径。

通过文件地址下载文件

package com.ruoyi.im.utils;

import com.ruoyi.common.config.RuoYiConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class FileUtils {

    /**
     * 默认路径
     */
    private static String defaultBaseDir = RuoYiConfig.getProfile();

    /**
     * 下载并保存文件
     *
     * @param url              url
     * @param originalFileName 原始文件名字
     * @return {@code String}
     */
    public static String downloadAndSaveFile(String url, String originalFileName) {
        try {
            URL fileUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) fileUrl.openConnection();
            connection.setRequestMethod("GET");

            String fileName = generateFileNameWithTimestamp(originalFileName);
            String savePath = generateSavePath(fileName);

            try (InputStream inputStream = connection.getInputStream();
                 BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(savePath))) {

                byte[] buffer = new byte[4096];
                int bytesRead;

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }

                return convertToReturnPath(savePath);
            }

        } catch (IOException e) {
            e.printStackTrace();
            log.error("Error: " + e.getMessage());
            return null;
        }
    }

    /**
     * 生成文件名字和时间戳
     *
     * @param originalFileName 原始文件名字
     * @return {@code String}
     */
    private static String generateFileNameWithTimestamp(String originalFileName) {
        String timestamp = getCurrentTimestamp();
        int dotIndex = originalFileName.lastIndexOf(".");
        String extension = "";
        if (dotIndex != -1) {
            extension = originalFileName.substring(dotIndex);
            originalFileName = originalFileName.substring(0, dotIndex);
        }
        return originalFileName + "_" + timestamp + extension;
    }

    /**
     * 生成保存路径
     *
     * @param fileName 文件名称
     * @return {@code String}
     */
    private static String generateSavePath(String fileName) {
        Date currentDate = new Date();
        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
        SimpleDateFormat dayFormat = new SimpleDateFormat("dd");

        String year = yearFormat.format(currentDate);
        String month = monthFormat.format(currentDate);
        String day = dayFormat.format(currentDate);

        String filePath = defaultBaseDir + "/upload/" + year + "/" + month + "/" + day + "/";
        return filePath + fileName;
    }

    /**
     * 转换返回路径
     *
     * @param filePath 文件路径
     * @return {@code String}
     */
    private static String convertToReturnPath(String filePath) {
        String relativePath = filePath.replace(defaultBaseDir, "/profile");
        return relativePath.replace("\\", "/");
    }

    /**
     * 获得当前时间戳
     *
     * @return {@code String}
     */
    public static String getCurrentTimestamp() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date currentDate = new Date();
        return dateFormat.format(currentDate);
    }
}

用于根据文件URL地址处理文件的下载、保存和路径转换操作。下面对代码的各个部分进行简要介绍:

  1. 导入和日志记录:导入了所需的类和包,使用了 @Slf4j 注解来自动生成日志记录代码。

  2. 默认路径和方法

    • defaultBaseDir:默认的文件保存路径,通过 RuoYiConfig.getProfile() 方法获取,您需要将其设置为实际的文件保存目录。
    • downloadAndSaveFile(String url, String originalFileName):下载文件并保存到本地,接收文件的 URL 和原始文件名作为参数。
    • generateFileNameWithTimestamp(String originalFileName):根据原始文件名生成带时间戳的新文件名。
    • generateSavePath(String fileName):根据文件名生成保存的文件路径,包括年、月、日的子目录。
    • convertToReturnPath(String filePath):将文件路径转换为返回的相对路径格式。
  3. 下载文件逻辑:在 downloadAndSaveFile 方法中,通过创建一个 URL 连接,打开连接并获取文件流。然后使用输入流和输出流将文件保存到本地指定的目录中,生成新的文件名以避免冲突。

  4. 生成保存路径:使用当前日期和时间生成保存文件的路径,包括年、月和日的子目录。

  5. 转换返回路径:将保存的文件路径转换为相对于默认路径 /profile 的相对路径格式。

  6. 获取当前时间戳:通过 getCurrentTimestamp 方法获取当前时间的时间戳,精确到秒,用于生成带时间戳的文件名。

具体使用

很简单,直接调用即可!!!

@GetMapping("/download")
    public AjaxResult downloadFilebyUrl(@RequestParam String url, @RequestParam String fielName) {
        String path = FileUtils.downloadAndSaveFile(url, fielName);
        if (StringUtils.isNotBlank(path)) {
            return AjaxResult.success(path);
        } else {
            return AjaxResult.error("文件下载失败!!!");
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/879026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

发布游戏,进行打包。(Unity)

做到这里,我们的项目基本功能已经完成了,如果你还想使项目功能更加完善,可以自己思考如何补充,充分发挥并进行优化使效果达到更加美好。 首先呢,我们这里是说打包Window电脑游戏,我们直接点击菜单栏文件-&…

数据结构与算法基础(青岛大学-王卓)(7)

差点就脱更了啊,微臣嘴干玩死,忙碌的暑假,还有头痛的new house, 我这junk food 也是吃一大堆,please不要长胖啊。 图的应用 这一章内容也是很多啊,概念真是比牛毛还多。。。看了两遍才缓过来啊 fighting 文章目录 [toc…

DoIP学习笔记系列:(六)满足AES128-CMAC算法的“安全认证”.dll生成实践

文章目录 1. 算法Demo2. 算法实现传送门 DoIP学习笔记系列:导航篇 AES128-CMAC算法在汽车电子控制单元的软件开发中涉及到安全相关的需求经经常用到,具体的算法原理请各位小伙伴自行百度,本篇主要向大家分享该算法如何集成到.dll文件中,在OTA、刷写等场景作为$27服务的安全…

Python实现透明隧道爬虫ip:不影响现有网络结构

作为一名专业爬虫程序员,我们常常需要使用隧道代理来保护个人隐私和访问互联网资源。本文将分享如何使用Python实现透明隧道代理,以便在保护隐私的同时不影响现有网络结构。通过实际操作示例和专业的解析,我们将带您深入了解透明隧道代理的工…

微服务相关面试题

👏作者简介:大家好,我是爱写博客的嗯哼,爱好Java的小菜坤 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 📝社区论坛:希望大家能加入社区共同进步…

自动化测试系列 —— UI测试

UI 测试是一种测试类型,也称为用户界面测试,通过该测试,我们检查应用程序的界面是否工作正常或是否存在任何妨碍用户行为且不符合书面规格的 BUG。了解用户将如何在用户和网站之间进行交互以执行 UI 测试至关重要,通过执行 UI 测试…

解决生成式AI落地之困,亚马逊云科技提供完整解决方案

生成式AI技术无疑是当前最大的时代想象力之一。 资本、创业者、普通人都在涌入生成式AI里去一探究竟:“百模大战”连夜打响,融资规模连创新高,各种消费类产品概念不断涌现……根据Bloomberg Intelligence 的报告,2022年生成式AI 市…

[HDLBits] Exams/m2014 q4c

Implement the following circuit: module top_module (input clk,input d, input r, // synchronous resetoutput q);always(posedge clk) beginif(r) q<1b0;elseq<d;end endmodule

万字长文·通俗易懂·一篇包掌握——输入/输出·文件操作(c语言超详细系列)(二)

前言&#xff1a;Hello&#xff0c;大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;上一节我们主要学习了格式化输入输出的基本内容&#xff0c;这一节我们对格式化进行更加深入的了解&#xff0c;对文件概念进行介绍&#xff0c;并且对输入、输出与文件读写的基本概念…

推断统计(独立样本t检验)

这里我们是采用假设检验中的独立样本t 检验来比较两个独立正态总体均值之间是否存在显著性差异&#xff0c;以比较城市与农村孩子的心理素质是否有显著差异为例 。 这里我们首先是假设城市孩子与农村孩子心理素质无显著差异&#xff0c;但是此时方差是否齐性是未知的&#xff0…

IntelliJ IDEA(简称Idea) 基本常用设置及Maven部署---详细介绍

一&#xff0c;Idea是什么&#xff1f; 前言&#xff1a; 众所周知&#xff0c;现在有许多编译工具&#xff0c;如eclipse&#xff0c;pathon, 今天所要学的Idea编译工具 Idea是JetBrains公司开发的一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于Java…

4.文件保护

第四章 文件管理 4.文件保护 ​   加密保护&#xff1a;可以用“密码”与文件的原始数据依次做异或运算。这样可以把整个文件的数据都进行加密&#xff0c;所以系统中保存的并不是文件的原始数据&#xff0c;而是保存了对文件进行加密之后的数据&#xff0c;所以如果一个用户…

Windows Oracle21C与PLSQL Developer 15配置

1、下载Oracle21c并安装 下载地址&#xff1a;https://www.oracle.com/database/technologies/oracle21c-windows-downloads.html 2、下载PLSQL Developer 15并安装 下载地址&#xff1a;https://www.allroundautomations.com/products/pl-sql-developer/#pricing 3、配置O…

Android Studio瀑布流实现

效果&#xff1a; ImageDetail class package com.example.waterfallflow; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.ImageView;public class ImageDetail extends Activity{Overrideprotected void …

SCAU操作系统知识点之(十一)I/O调度和磁盘调度

1、程序控制I/O&#xff1a;CPU忙等I/O结束&#xff0c;CPU与设备串行工作。 2、中断驱动I/O&#xff1a;各种设备通用&#xff0c;中断次数多。 3、直接存储器访问DMA原理与I/O过程。 列出并简单定义执行I/O的三种技术。 程序控制I/O&#xff1a; 处理器代表进程向I/O模…

【Java】使用JavaSE实现图书管理系统详解

目录 1.前言 2.初步框架搭建 3.Book 书架和书架里的书 3.1书本 3.2书架 4.User 用户和管理员 4.1初步想法 4.2用户 4.3管理员 4.4main函数中如何调用不同的成员 5.方法的调用 5.1接口 5.2增加图书 5.3借阅图书 5.4删除图书 5.5退出系统 5.6查找图书 5.7归还图书…

利用python实现激光雷达LAS数据滤波的7种方式,使用laspy读写

激光雷达&#xff08;LiDAR&#xff09;数据在实际应用中可能受到噪声和不完美的测量影响&#xff0c;因此数据去噪和滤波方法变得至关重要&#xff0c;以提高数据质量和准确性。以下是一些常用的激光雷达数据去噪与滤波方法。 原始数据如下&#xff1a; 1. 移动平均滤波&…

springcloud3 hystrix实现服务降级,熔断,限流以及案例配置

一 hystrix的作用 1.1 降级&#xff0c;熔断&#xff0c;限流 1.服务降级&#xff1a; A方案出现问题&#xff0c;切换到兜底方案B&#xff1b; 2.服务熔断&#xff1a;触发规则&#xff0c;出现断电限闸&#xff0c;服务降级 3.服务限流&#xff1a;限制请求数量。 二 案例…

uni-app中使用pinia

目录 Pinia 是什么&#xff1f; uni-app 使用Pinia main.js 中引用pinia 创建和注册模块 定义pinia方式 选项options方式 定义pinia 页面中使用 pinia选项options方式 函数方式 定义pinia 页面中使用 函数方式 定义的pinia Pinia 是什么&#xff1f; Pinia&#xff0…

ES中倒排索引机制

在ES的倒排索引机制中有四个重要的名词&#xff1a;Term、Term Dictionary、Term Index、Posting List。 Term&#xff08;词条&#xff09;&#xff1a;词条是索引里面最小的存储和查询单元。一段文本经过分析器分析以后就会输出一串词条。一般来说英文语境中词条是一个单词&a…