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
     * <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);

/**
     * 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());

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)手动删除

// 操作完上的文件 需要删除在根目录下生成的文件
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子类型

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

在这里插入图片描述
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;
}

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

@PostMapping(value = "/uploadSql")
@Operation(summary = "全部查询接口表SQL信息", description = "全部查询接口表SQL信息")
public ApiResponse<InterfaceSql> uploadSql(@RequestParam("file") MultipartFile  file) {
    return interfaceSqlAppService.uploadSql(file);
}
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】后端从数据库查询内容,然后把内容放进文件中,供前端下载

@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);
}
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();
}
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格式,并下载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值