• Java的File文件操作案例汇总


    案例汇总

    【1】MultipartFile与File的互转

    (1)前言

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

    (2)MultipartFile转File

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

    (1)FileUtils.copyInputStreamToFile转换

    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
         * 

    * 项目根路径创建临时文件,转换得到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; } }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

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

    (2)multipartFile.transferTo(tempFile);

    /**
         * MultipartFile转File
         * 

    * 项目根路径创建缓冲区来实现这个转换 * * @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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注意:
    1.防止生成的临时文件,createTempFile()方法会在文件名后添加随机码
    2.生成的文件不会立马删除,而是在jvm退出时执行删除此路径下的文件

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

    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;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

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

    (3)手动删除

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

    (4)File转MultipartFile

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

    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile
    
    • 1

    在这里插入图片描述
    MultipartFile是一个接口,因此转成MultipartFile格式需要转成实现MultipartFile接口的实现类即可

    在这里插入图片描述

    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

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

    @PostMapping(value = "/uploadSql")
    @Operation(summary = "全部查询接口表SQL信息", description = "全部查询接口表SQL信息")
    public ApiResponse<InterfaceSql> uploadSql(@RequestParam("file") MultipartFile  file) {
        return interfaceSqlAppService.uploadSql(file);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

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

    @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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

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

  • 相关阅读:
    Java关键字说明
    Luogu P1966: [NOIP2013 提高组] 火柴排队 [树状数组+逆序对]
    简单四边形不等式优化dp(下)
    计划管理这一块儿,ERP和MES真的划等号?
    freertos定时器任务运行流程()
    Android-自定义流布局标签
    【无标题】关于市面上的几款FOC驱动芯片讲解
    Latex语法学习08:打通latex、mathml和word公式转换
    (二十)大数据实战——Flume数据采集的基本案例实战
    使用gcc编译.s汇编
  • 原文地址:https://blog.csdn.net/weixin_44823875/article/details/133796037