保存文件到指定位置,读取/删除指定文件夹中文件

使用背景

用户每次上传的文件太多,如果批量处理,服务器性能不够,所以将用户上传的文件保存到服务器上,再启动一个线程,依次处理完成后删除文件

用户上传文件

java 复制代码
    @PostMapping("/inFile")
    public String inFile(@RequestParam("file") List<MultipartFile> listFile, @RequestParam Map<String,String> params){
        // 创建临时文件夹
        FileSaveClear fsc = new FileSaveClear();
        fsc.createTempDirectory();

        listFile.forEach(file->{
            // 保存上传的文件到临时文件夹
            String filePath = fsc.saveFileToTemp(file);
        });
        //读取到指定文件夹中的所有文件
        List<MultipartFile> files = fsc.getAllTempFilesAsMultipartFiles();
        //启动一个线程处理对应的文件
        new Thread(()->{
            System.out.println(LocalDateTime.now());
            files.forEach(file->{
                inFileRun(file,params);
            });
            //删除对应的文件
            fsc.deleteAllFilesInDirectory();
            System.out.println(LocalDateTime.now());
        }).start();
        return "inFile";
    }

文件保存/读取/删除代码

java 复制代码
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class FileSaveClear {
    final String TEMP_FILE_PATH = System.getProperty("user.dir") + "/temp-files/";
    // 创建临时文件夹
    public void createTempDirectory() {
        File tempDir = new File(TEMP_FILE_PATH);
        if (!tempDir.exists()) {
            tempDir.mkdirs();
        }
    }

    // 保存文件到临时文件夹
    public String saveFileToTemp(MultipartFile file) {
        try {
            String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
            String filePath = TEMP_FILE_PATH + fileName;
            File destFile = new File(filePath);
            file.transferTo(destFile);
            return filePath;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除指定文件夹中的所有文件
     * @return 删除成功的文件数量
     */
    public int deleteAllFilesInDirectory() {
        File directory = new File(TEMP_FILE_PATH);
        if (!directory.exists() || !directory.isDirectory()) {
            return 0;
        }

        File[] files = directory.listFiles();
        if (files == null) {
            return 0;
        }

        int deletedCount = 0;
        for (File file : files) {
            if (file.isFile() && file.delete()) {
                deletedCount++;
            }
        }

        return deletedCount;
    }

    /**
     * 读取临时文件夹中的所有文件,返回MultipartFile对象列表
     * @return MultipartFile对象列表
     */
    public List<MultipartFile> getAllTempFilesAsMultipartFiles() {
        File tempDir = new File(TEMP_FILE_PATH);
        if (!tempDir.exists() || !tempDir.isDirectory()) {
            return new ArrayList<>();
        }

        File[] files = tempDir.listFiles();
        if (files == null) {
            return new ArrayList<>();
        }

        List<MultipartFile> multipartFiles = new ArrayList<>();
        for (File file : files) {
            if (file.isFile()) {
                try {
                    // 读取文件内容
                    byte[] fileContent = java.nio.file.Files.readAllBytes(file.toPath());

                    // 创建MultipartFile对象 - 使用自定义实现
                    MultipartFile multipartFile = new MultipartFile() {
                        @Override
                        public String getName() {
                            return file.getName();
                        }

                        @Override
                        public String getOriginalFilename() {
                            return file.getName();
                        }

                        @Override
                        public String getContentType() {
                            // 根据文件扩展名确定内容类型
                            String fileName = file.getName().toLowerCase();
                            if (fileName.endsWith(".csv")) {
                                return "text/csv";
                            } else if (fileName.endsWith(".txt")) {
                                return "text/plain";
                            } else if (fileName.endsWith(".xlsx") || fileName.endsWith(".xls")) {
                                return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                            } else {
                                return "application/octet-stream";
                            }
                        }

                        @Override
                        public boolean isEmpty() {
                            return fileContent.length == 0;
                        }

                        @Override
                        public long getSize() {
                            return fileContent.length;
                        }

                        @Override
                        public byte[] getBytes() throws IOException {
                            return fileContent;
                        }

                        @Override
                        public InputStream getInputStream() throws IOException {
                            return new ByteArrayInputStream(fileContent);
                        }

                        @Override
                        public void transferTo(File dest) throws IOException, IllegalStateException {
                            java.nio.file.Files.write(dest.toPath(), fileContent);
                        }
                    };

                    multipartFiles.add(multipartFile);
                } catch (Exception e) {
                    System.err.println("读取文件 " + file.getName() + " 时出错: " + e.getMessage());
                }
            }
        }

        return multipartFiles;
    }
}
相关推荐
aaPIXa6221 分钟前
C++模板元编程:编译期计算Fibonacci数列
java·开发语言·c++
SunnyDays10118 分钟前
Java 编辑 PDF:从增删改查到加密保护
java·修改 pdf·编辑 pdf
张三丰214 分钟前
Agent 不只是聊天框:用 ArkUI 做一个鸿蒙任务工作台
后端
卷无止境21 分钟前
从Python的cryptography库出发,从零开始理解密码学,到构建零信任网络
后端·python
Augustzero23 分钟前
`co_await` 按下暂停键之后:从零看懂 C++20 协程
c++·后端
球king24 分钟前
CC GUI 插件:在 IDEA 中使用 CodeX
java·ide·intellij-idea
宠友信息25 分钟前
多端即时通讯源码技术实践,Redis路由、MySQL持久化与Socket接入
spring boot·websocket·mysql·uni-app
豆瓣鸡1 小时前
网关、服务 userId 透传
java·微服务·gateway
bksczm1 小时前
Linux之信号量(POSIX标准)
java·开发语言
Tom·Ge1 小时前
【Spring Boot 4】Spring Boot 4.0 AI Agent实战:Skills Agent + MCP协议集成
人工智能·spring boot·microsoft