Java 文件上传,下载,复制,删除,Zip文件解压缩,文件内容修改,JSON 文件中字段值的修改,递归删除文件夹及其子文件等

Java 文件上传,下载,复制,删除,Zip文件解压缩,文件内容修改,JSON 文件中字段值的修改,递归删除文件夹及其子文件等

  • Controller
  • FileUtil

Controller

  • 文件批量上传
  • 批量删除文件
  • 文件下载
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;@Slf4j
@RestController
@AllArgsConstructor
@Api(tags = "文件相关操作接口")
@RequestMapping("/file")
public class FileController
{/*** @param files 文件列表* @param tempFilePath 临时文件路径*/@ApiOperation(value = "文件批量上传")@PostMapping("/uploadFiles")public Result<?> uploadFiles(@RequestParam(value = "file") MultipartFile[] files, String tempFilePath){List<Map<String, Object>> list;try{list = FileUtil.uploadFiles(files, tempFilePath);} catch (Exception e){return Result.fail(e.getMessage());}return Result.success(list);}/*** @param fileNames 文件名称列表* @param targetPath 目标路径*/@PostMapping("/deleteFiles")@ApiOperation("批量删除文件")public void deleteFiles(@RequestParam(value = "files") String[] fileNames, String targetPath){FileUtil.deleteFiles(fileNames, targetPath);}/*** 文件下载,1.如果有文件名称,则将文件名称拼接到路径后进行下载;2.否则直接根据路径下载;* 第一种情况:filePath=”D:/file“;fileName=“test.txt”;* 第二种情况:filePath=”D:/file/test.txt“;fileName=“”;* @param filePath 文件路径(必填)* @param fileName 文件名称(可选)* @return ResponseEntity*/@ApiOperation("文件下载")@GetMapping("/download")public ResponseEntity<Resource> download(@RequestParam String filePath, String fileName){try{return FileUtil.download(filePath, fileName);} catch (Exception e){log.error("文件下载失败", e);throw new RuntimeException(e);}}}

FileUtil

  • 文件批量上传
  • 批量删除文件
  • 文件下载
  • 压缩包校验
  • Zip文件解压缩
  • 创建文件夹
  • 递归地删除文件夹及其所有内容
  • 复制文件夹中的所有内容
  • 复制文件,将从源目录中的文件复制到目标目录中
  • 修改 JSON 文件中指定字段的值
  • 修改文件内容
@Slf4j
public class FileUtil
{/*** 上传文件* @param files 文件列表* @param targetPath 目标路径* @return*/public static List<Map<String, Object>> uploadFiles(MultipartFile[] files, String targetPath){int size = 0;for (MultipartFile file : files){size = (int) file.getSize() + size;}List<Map<String, Object>> fileInfoList = new ArrayList<>();for (int i = 0; i < files.length; i++){Map<String, Object> map = new HashMap<>();String fileName = files[i].getOriginalFilename();//获取文件后缀//            String afterName = StringUtils.substringAfterLast(fileName, ".");//获取文件前缀//            String prefName = StringUtils.substringBeforeLast(fileName, ".");//            String fileServiceName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + i + "_" + prefName//                    + "." + afterName;String fileServiceName = UUID.randomUUID().toString().replace("-", "") + "_" + fileName;File filePath = new File(targetPath, fileServiceName);map.put("fileServiceName", fileServiceName);map.put("fileName", fileName);map.put("filePath", filePath);// 判断文件父目录是否存在if (!filePath.getParentFile().exists()){filePath.getParentFile().mkdirs();}try{files[i].transferTo(filePath);} catch (IOException e){log.error("文件上传失败", e);throw new CustomException("文件上传失败");}fileInfoList.add(map);}return fileInfoList;}/*** 批量删除文件** @param fileNames 文件名称数组*/public static void deleteFiles(String[] fileNames, String targetPath){for (String fileName : fileNames){String filePath = targetPath + fileName;File file = new File(filePath);if (file.exists()){try{Files.delete(file.toPath());} catch (IOException e){e.printStackTrace();log.warn("文件删除失败", e);}} else{log.warn("文件: {} 删除失败,该文件不存在", fileName);}}}/*** 文件下载* @param filePath 文件路径(必填)* @param fileName 文件名称(可选)* @return ResponseEntity*/public static ResponseEntity<Resource> download(String filePath, String fileName)throws MalformedURLException, UnsupportedEncodingException{// 加载文件资源Resource resource = loadFileAsResource(filePath, fileName);// 避免中文乱码String encodedFileName = URLEncoder.encode(Objects.requireNonNull(resource.getFilename()), "UTF-8").replaceAll("\\+", "%20");// 确定文件的内容类型return ResponseEntity.ok().contentType(MediaType.parseMediaType(ContentType.OCTET_STREAM.getValue())).header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName).body(resource);}/*** 加载文件资源* @param filePath 文件路径(必填)* @param fileName 文件名称(选填)* @return Resource* @throws MalformedURLException URL格式异常*/private static Resource loadFileAsResource(String filePath, String fileName) throws MalformedURLException{Path path;if (StringUtils.isEmpty(fileName)){path = Paths.get(filePath);} else{path = Paths.get(filePath + File.separator + fileName);}Resource resource = new UrlResource(path.toUri());if (resource.exists() || resource.isReadable()){return resource;} else{throw new RuntimeException("找不到文件或无法读取文件");}}/*** 压缩包校验* @param zipFilePath 压缩包文件路径* @param suffix 文件后缀* @throws Exception*/public static void zipVerify(String zipFilePath, String suffix) throws Exception{// 打开压缩文件try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(Paths.get(zipFilePath)))){ZipEntry entry = zipInputStream.getNextEntry();boolean allFilesAreSameSuffix = true;// 遍历压缩文件中的条目while (entry != null){String entryName = entry.getName();if (!entryName.toLowerCase().endsWith(suffix)){allFilesAreSameSuffix = false;break;}zipInputStream.closeEntry();entry = zipInputStream.getNextEntry();}// 如果存在非.pak文件则校验失败if (!allFilesAreSameSuffix){throw new RuntimeException("压缩包中存在非" + suffix + "文件,校验失败");}}}/*** Zip文件解压缩* @param zipFilePath 压缩包文件路径* @param destDirectory 目标目录* @throws IOException*/public static List<String> unzip(String zipFilePath, String destDirectory) throws Exception{// 文件名列表List<String> fileNameList = new ArrayList<>();// 创建目标文件夹File destDir = new File(destDirectory);if (!destDir.exists()){destDir.mkdirs();}// 读取并解压文件try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(Paths.get(zipFilePath)))){ZipEntry entry = zipInputStream.getNextEntry();byte[] buffer = new byte[1024];// 解压文件while (entry != null){String entryName = entry.getName();File newFile = new File(destDirectory + File.separator + entryName);try (FileOutputStream fos = new FileOutputStream(newFile)){int len;while ((len = zipInputStream.read(buffer)) > 0){fos.write(buffer, 0, len);}}zipInputStream.closeEntry();fileNameList.add(entryName);entry = zipInputStream.getNextEntry();}}log.info("解压缩并校验完成");return fileNameList;}/*** 创建文件夹* @param folderPath*/public static void createFolder(String folderPath){File folder = new File(folderPath);if (!folder.exists()){if (!folder.mkdirs()){throw new RuntimeException("文件夹创建失败: " + folderPath);}}}/*** 递归地删除文件夹及其所有内容* @param folderPath 文件夹路径*/public static void deleteFolder(String folderPath){File folder = new File(folderPath);if (folder.exists()){File[] files = folder.listFiles();if (files != null){for (File file : files){if (file.isDirectory()){deleteFolder(file.getAbsolutePath());} else{file.delete();}}}folder.delete();log.info("文件夹{}删除成功!", folderPath);}}/*** 复制文件夹中的所有内容* @param sourceFolderPath 源文件夹路径       例如:D:/XXX/AAA/BBB/CCC* @param targetFolderPath 目标文件夹路径      例如:D:/YYY/BBB/CCC/DDD* @param newFolderName 新文件夹名称           例如:EEE* @return 目标文件路径                        例如:D:/YYY/BBB/CCC/DDD/EEE*/public static String copyFolderOfAll(String sourceFolderPath, String targetFolderPath, String newFolderName){String destinationFolderPath = targetFolderPath + File.separator + newFolderName;Path sourcePath = Paths.get(sourceFolderPath);Path destinationPath = Paths.get(destinationFolderPath);try{// 遍历源文件夹中的所有文件和子文件夹Files.walk(sourcePath).forEach(source -> {try{// 构建目标文件夹中的对应路径Path destination = destinationPath.resolve(sourcePath.relativize(source));if (Files.isDirectory(source)){if (!Files.exists(destination)){Files.createDirectory(destination);}} else{Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);}} catch (IOException e){throw new RuntimeException("复制文件夹失败: " + e.getMessage());}});} catch (Exception e){log.error("文件夹复制失败: {}", e);FileUtil.deleteFolder(destinationFolderPath);throw new RuntimeException("文件夹复制失败");}return destinationFolderPath;}/*** 复制文件,将从源目录中的文件复制到目标目录中* @param sourceFilePath 源文件路径* @param destinationDirectory 目标目录* @param newFileName 新文件名称*/public static void copeFile(String sourceFilePath, String destinationDirectory, String newFileName){Path sourceFile = Paths.get(sourceFilePath);Path destinationFile = Paths.get(destinationDirectory, newFileName);try{Files.copy(sourceFile, destinationFile);log.info("File copied successfully from " + sourceFile + " to " + destinationFile);} catch (IOException e){log.error("Error copying file: " + e.getMessage());}}/*** 修改JSON文件中指定字段的值* @param filePath 文件路径* @param fieldName 字段名* @param newValue 新值*/public static void modifyJsonField(String filePath, String fieldName, Object newValue){try{ObjectMapper objectMapper = new ObjectMapper();File file = new File(filePath);JsonNode jsonNode = objectMapper.readTree(file);if (jsonNode.isObject()){ObjectNode objectNode = (ObjectNode) jsonNode;objectNode.putPOJO(fieldName, newValue);objectMapper.writeValue(file, objectNode);log.info("Field '" + fieldName + "' in the JSON file has been modified to: " + newValue);} else{log.info("Invalid JSON format in the file.");}} catch (IOException e){throw new RuntimeException(e);}}/*** 修改文件内容* @param filePath 文件路径* @param searchString 查找字符串* @param replacement 替换值*/public static void modifyFileContent(String filePath, String searchString, String replacement){try{File file = new File(filePath);BufferedReader reader = new BufferedReader(new FileReader(file));String line;StringBuilder content = new StringBuilder();while ((line = reader.readLine()) != null){if (line.contains(searchString)){line = line.replace(searchString, replacement);}content.append(line).append("\n");}reader.close();BufferedWriter writer = new BufferedWriter(new FileWriter(file));writer.write(content.toString());writer.close();log.info("文件内容[" + searchString + "]已被修改为[" + replacement + "]");} catch (IOException e){throw new RuntimeException(e);}}
}

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

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

相关文章

sklearn【AUC-ROC】原理,以及绘制ROC曲线!

一、AUC-ROC 介绍 在分类任务中&#xff0c;特别是当数据集中的类别分布不平衡时&#xff0c;评估模型的性能变得尤为重要。AUC-ROC&#xff08;Area Under the Receiver Operating Characteristic Curve&#xff0c;受试者工作特征曲线下的面积&#xff09;是一种有效的评估指…

Vue3:组合式API的基本使用

一、前言 本文主要讲述在Vue3中组合式API的基本使用。 二、组合式API的写法 1、数据 组合式API中&#xff0c;数据在setup函数里面声明数据要在return中返回才能在模板中渲染使用如果数据类型不是响应式数据&#xff0c;当数据改变时&#xff0c;已经展示在页面上的数据不会…

S32 Design Studio PE工具配置Power_Manager

工具配置 基本就是默认配置就行&#xff0c;就是在这6个状态里面跳转&#xff0c;重点就是前面2个状态.这个是芯片的电源管理&#xff0c;跟产品的电源管理是两回事。 生成代码 在Generated_Code/pwrMan1.c 里面&#xff0c;对应刚才配置的信息&#xff0c;一共有6个状态。 …

ChatGPT在论文写作中的应用:提升表达与逻辑的双重助力

随着人工智能技术的快速发展&#xff0c;其在科研领域的应用也愈发广泛。AI不仅提升了科研创新的效率&#xff0c;还为科研人员带来了前所未有的便利。本文将从ChatGPT深度科研应用、数据分析及机器学习、AI绘图以及高效论文撰写等方面&#xff0c;综述AI如何助力科研创新与效率…

土壤水分检测仪中应用的数字电容传感芯片

土壤水分检测仪&#xff0c;它是基于频域反射&#xff08;Frequency Domain Reflectometry&#xff0c;FDR&#xff09;原理&#xff0c;能够准确对传感器周围的土壤水分情况进行监测,可对10cm、20cm、30cm、40cm、50cm的较多5个监测层面进行测量。广泛应用于农田蒸散、作物耗水…

【话题】程序员如何搞副业,简单探讨下

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 背景前提条件打造私域广结朋友平台 技能转化为价值1. 副业途径2. 如何开展3. 未来趋势与建议4. 挑战与策略5. 规划与发展 文章推荐 背景 程序员不仅拥有将抽象概念转化…

文献速递:深度学习胶质瘤诊断---使用深度学习在 MRI 图像中进行低级别胶质瘤的脑肿瘤分割和分级

Title 题目 Brain tumor segmentation and grading of lower-grade glioma using deeplearning in MRI images 使用深度学习在 MRI 图像中进行低级别胶质瘤的脑肿瘤分割和分级 01文献速递介绍 胶质瘤是最常见的脑肿瘤&#xff0c;根据肿瘤的恶性程度和生长速率具有不同的分级…

婴儿用的洗衣机买哪种好?四款超实用高质量婴儿洗衣机推荐!

近几年科技高速发展&#xff0c;我们的生活也因此变得更加便捷、健康高效。尤其是在家庭生活中&#xff0c;各种新兴家电的出现让我们的生活变得更加健康卫生。婴儿洗衣机也为现代家庭提供了极大的便捷。由于婴儿刚出生免疫力比较弱&#xff0c;所以建议婴儿的衣物尽量和大人的…

操作系统命令(贪吃蛇项目)

&#x1f3dd;1.获得句柄 GetStdHandle是⼀个Windows API函数。它用于从⼀个特定的标准设备&#xff08;标准输入、标准输出或标 准错误&#xff09;中取得⼀个句柄&#xff08;用来标识不同设备的数值&#xff09;&#xff0c;使用这个句柄可以操作设备。 ⛳️函数原型&…

多线程(60)SynchronousQueue和它的用途

SynchronousQueue是一个没有存储空间的阻塞队列&#xff0c;它是java.util.concurrent包中的一部分。每一个put操作必须等待一个take操作&#xff0c;反之亦然。SynchronousQueue内部并不维护任何元素的存储&#xff0c;可以认为它是一种线程之间一对一传递消息的机制。 核心特…

ArrayList的并集、交集、差集

并集&#xff1a; //并集操作&#xff1a;将另一个容器中的元素添加到当前容器中List<String> a new ArrayList<>(); a.add("a"); a.add("b"); a.add("c");List<String> b new ArrayList<>(); b.add("a");…

MySQL出现Waiting for table metadata lock的原因方法

MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)都无法进行,因为他们也会在Opening tables的阶段进入到Waiti…

力扣:219. 存在重复元素 II

力扣&#xff1a;219. 存在重复元素 II 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 …

SIP-7035 隧道广播功率放大器 校园网络广播功放sip定压功放

SIP-7035 隧道广播功率放大器 校园网络广播功放sip定压功放 产品介绍18123651365微信 SIP-7035是我司的一款合并式定压功放&#xff0c;支持标准SIP协议&#xff0c;具有10/100M以太网接口&#xff0c;后面板上有2组AUX音源输入和6.35mm接口的麦克风输入&#xff0c;可以输入…

Grass注册不了、按钮灰色的解决方案

近期相信grass挂机项目不少人有所有接触。还有不了解这个项目的可以看看博客&#xff1a; http://t.csdnimg.cn/bI4UO 但是不少人注册时遇到无法注册的问题&#xff0c;或者是注册按钮显示灰色&#xff0c;放上鼠标时显示禁止。这也是博主在尝试时遇到的问题。 经过探索&…

二维数组之前缀和下篇

在此之前&#xff0c;可以先去看看二维数组之二维前缀和首篇和二维数组之前缀和中篇。 最大子数组和 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 示例 1&#xff1a; …

RabbitMQ和Minio实现头像存储

使用 RabbitMQ 处理用户头像上传任务&#xff0c;同时将用户头像存储在 Minio 中是一个常见的应用场景。该示例将展示如何在 Spring Boot 项目中使用 RabbitMQ 和 Minio 实现此功能。示例包括两个部分&#xff1a;一是将头像上传任务推送到 RabbitMQ 队列中&#xff1b;二是从队…

GPT人工智能在线网页版大全

平民不参与内测&#xff0c;还能使用 ChatGPT 吗&#xff1f; 自去年 ChatGPT 爆红以来&#xff0c;关于它的消息铺天盖地。如果你真的想使用它&#xff0c;途径有很多。除了官方网站外国内还有许多 ChatGPT 的镜像网站&#xff0c;其中不乏免费的 3.5 版本。虽然有些网站需要…

2024年04月18日优雅草便民tools开源-git以及dcloud同步-长期更新

优雅草小工具-数据来自优雅草api赋能 优雅草小工具-数据来自优雅草api赋能-优雅草便民工具是一款由成都市一颗优雅草科技有限公司打造的便民查询公益工具&#xff0c;2024年1月17日正式发布v1.0.0版本&#xff0c;本工具为了方便大众免费使用&#xff0c;本生活小工具会陆续加入…

Mysql 为什么使用 B+Tree 作为索引结构

常规的数据库存储引擎&#xff0c;一般都是采用 B 树或者 B树来实现索引的存储。 因为 B 树是一种多路平衡树&#xff0c;用这种存储结构来存储大量数据&#xff0c;它的整个高度会相比二叉树来说&#xff0c;会矮很多。 而对于数据库来说&#xff0c;所有的数据必然都是存储在…