Java的File文件操作案例汇总

Java的File文件操作案例汇总

案例汇总

【1】MultipartFile与File的互转

(1)前言

需求是上传Excel文件并读取Excel文件中的内容,根据获取的数据执行完某些业务操作后再将一些数据写回到excel中。前台使用FormData表单的方式请求后台,后台接收类型是MultipartFile,放置文件过大时会造成内存溢出需要转换为File类型

(2)MultipartFile转File

其实转换的本质都是要创建一个file的临时文件,然后通过各种实现方式将MultipartFile中的内容写入到file中

(1)FileUtils.copyInputStreamToFile转换

java 复制代码
package com.cxstar.file.util;

import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * @author zhouquan
 * @description 测试MultipartFile与File互转
 * @date 2023-03-12 17:31
 **/
public class FileTestUtils {


    /**
     * MultipartFile转File
     * <p>
     * 项目根路径创建临时文件,转换得到File,再删除临时文件
     *
     * @param multipartFile
     * @return
     */
    public static File multiPartFileToFile(MultipartFile multipartFile) throws IOException {

        //获取文件名
        String originalFilename = multipartFile.getOriginalFilename();

        //获取默认定位到的当前用户目录("user.dir"),也就是当前应用的根路径
        String tempDir = System.getProperty("user.dir");

        //根目录下生成临时文件
        File file = new File(tempDir+File.separator+originalFilename);

        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);

        return file;
    }

}

此种方式的弊端就是需要在调用此方法后需要再手动删除,也就是要在业务代码中再掺杂删除的逻辑。

(2)multipartFile.transferTo(tempFile);

java 复制代码
/**
     * MultipartFile转File
     * <p>
     * 项目根路径创建缓冲区来实现这个转换
     *
     * @param multipartFile
     * @return
     */
    public static File multiPartFileToFile2(MultipartFile multipartFile) throws IOException {

        //获取文件名
        String originalFilename = multipartFile.getOriginalFilename();

        //获取默认定位到的当前用户目录("user.dir"),也就是当前应用的根路径
        String tempDir = System.getProperty("user.dir");

        //获取文件名
        String filename = StringUtils.substringBeforeLast(originalFilename, ".");
        //获取文件后缀
        String fileExt = StringUtils.substringAfterLast(originalFilename, ".");

        //在项目根路径生成临时文件
        File tempFile = File.createTempFile(filename, "." + fileExt, new File(tempDir));

        multipartFile.transferTo(tempFile);

        //在jvm退出时执行删除此路径下的文件
        tempFile.deleteOnExit();

        return tempFile;
    }

注意:

1.防止生成的临时文件,createTempFile()方法会在文件名后添加随机码

2.生成的文件不会立马删除,而是在jvm退出时执行删除此路径下的文件

(3)(推荐)FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());

java 复制代码
package com.cxstar.file.util;

import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

/**
 * @author zhouquan
 * @description 测试MultipartFile与File互转
 * @date 2023-03-12 17:31
 **/
public class FileTestUtils {
    /**
     * MultipartFile 转 File
     *
     * @param multipartFile
     * @throws Exception
     */
    public static File multiPartFileToFile3(MultipartFile multipartFile) {
        File file = null;
        if (multipartFile.isEmpty()) {
            return null;
        }

        try {
            //本质上还是在项目根路径创建文件
            file = new File(multipartFile.getOriginalFilename());

            //将MultipartFile的byte[]写入到file中
            FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());

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

此种方式相较于第二种方式,文件名不会发生改变,当然还是要手动删除

(3)手动删除

java 复制代码
// 操作完上的文件 需要删除在根目录下生成的文件
File f = new File(sqlFile.toURI());
if (f.delete()){
    System.out.println("删除成功");
}else {
    System.out.println("删除失败");
}

(4)File转MultipartFile

(1)File转MultipartFile

MultipartFile文件上传时,其实springmvc已经转为StandardMultipartFile子类型

java 复制代码
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile

MultipartFile是一个接口,因此转成MultipartFile格式需要转成实现MultipartFile接口的实现类即可

java 复制代码
package com.cxstar.file.util;

import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;

/**
 * @author zhouquan
 * @description 测试MultipartFile与File互转
 * @date 2023-03-12 17:31
 **/
public class FileTestUtils {
    public static MultipartFile getMultipartFile(File file) throws Exception {
        MultipartFile multipartFile = new MockMultipartFile(file.getName(), new FileInputStream(file));
        return multipartFile;
}

【2】前端上传文件,后端解析出文件的名称和内容,然后存储到数据库

java 复制代码
@PostMapping(value = "/uploadSql")
@Operation(summary = "全部查询接口表SQL信息", description = "全部查询接口表SQL信息")
public ApiResponse<InterfaceSql> uploadSql(@RequestParam("file") MultipartFile  file) {
    return interfaceSqlAppService.uploadSql(file);
}
java 复制代码
public DomainResponse<InterfaceSql> uploadSql(MultipartFile file) {
    if (file.isEmpty()) {
        throw new YTRuntimeException("上传失败,请选择文件");
    }
    File sqlFile = null;
    try {
        //本质上还是在项目根路径创建文件
        sqlFile = new File(file.getOriginalFilename());
        //将MultipartFile的byte[]写入到file中
        FileUtils.writeByteArrayToFile(sqlFile, file.getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }

    String fileName = file.getOriginalFilename();
    StringBuilder fileContent = new StringBuilder();
    try (BufferedReader br = new BufferedReader(new FileReader(sqlFile))) {
        String line;
        while ((line = br.readLine()) != null) {
            fileContent.append(line).append("\n");
        }
    } catch (IOException e) {
        throw new YTRuntimeException("读取文件失败");
    }
    String sqlContent = fileContent.toString();

    InterfaceSql interfaceSql = new InterfaceSql();
    interfaceSql.setFileName(fileName);
    interfaceSql.setFileContent(sqlContent);

    interfaceSqlRepo.create(interfaceSql);

    // 操作完上的文件 需要删除在根目录下生成的文件
    File f = new File(sqlFile.toURI());
    if (f.delete()){
        System.out.println("删除成功");
    }else {
        System.out.println("删除失败");
    }

    return DomainResponse.ok(interfaceSql);
}

【3】后端从数据库查询内容,然后把内容放进文件中,供前端下载

java 复制代码
@GetMapping(value = "/downloadSql/{INTERFACE_SQL_id}")
@Operation(summary = "全部查询接口表SQL信息", description = "全部查询接口表SQL信息")
public ApiResponse<Void> downloadSql(@PathVariable("INTERFACE_SQL_id") String  id, HttpServletResponse response) {
    return interfaceSqlAppService.downloadSql(id,response);
}
java 复制代码
public DomainResponse<Void> downloadSql(String id,HttpServletResponse response)  {
    InterfaceSql interfaceSql = interfaceSqlRepo.queryById(id);
    String fileName = interfaceSql.getFileName();
    String fileContent = interfaceSql.getFileContent();
    try {
        FileUDUtil.downloadDbData(response,fileName,fileContent);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    return DomainResponse.ok();
}
java 复制代码
public static void downloadDbData(HttpServletResponse response, String fileName, String fileContent) throws IOException {
    if (ObjectUtil.isEmpty(fileName)) {
        throw new YTRuntimeException("文件名称不允许为空");
    }
    try {
        // 创建File对象
        File file = new File(fileName);
        // 创建FileOutputStream和BufferedOutputStream
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        // 将字符串内容写入文件
        bos.write(fileContent.getBytes());

        // 关闭流
        bos.close();
        fos.close();

        // 设置响应头
        response.setHeader("Content-Disposition", "attachment;filename="+fileName);

        // 获取OutputStream对象
        OutputStream os = response.getOutputStream();

        // 创建FileInputStream和byte数组
        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];

        // 将文件内容写入到客户端
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }

        // 关闭流
        fis.close();
        os.close();
    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

【4】生成文件到指定文件夹,然后将文件夹压缩成zip格式,并下载

相关推荐
侧耳倾听1113 分钟前
java集合相关的api-总结
java·开发语言
贺函不是涵16 分钟前
【沉浸式求职学习day43】【Java面试题精选3】
java·开发语言·学习
xiaobin8899922 分钟前
matlab官方免费下载安装超详细教程2025最新matlab安装教程(MATLAB R2024b)
java·开发语言·其他·matlab
Takoony26 分钟前
正则表达式r前缀使用指南
开发语言·正则表达式·r语言
搏博32 分钟前
WPS中代码段的识别方法及JS宏实现
开发语言·javascript·wps
vortex537 分钟前
Bash fork 炸弹 —— :(){ :|:& };:
运维·服务器·开发语言·网络安全·bash
小伍_Five42 分钟前
spark数据处理练习题详解【下】
java·大数据·spark·scala
Pacify_The_North1 小时前
【进程控制二】进程替换和bash解释器
linux·c语言·开发语言·算法·ubuntu·centos·bash
xiaohanbao091 小时前
day29 python深入探索类装饰器
开发语言·python·学习·机器学习·pandas
L汐1 小时前
02 K8s双主安装
java·容器·kubernetes