一种利用多部分文件问题的Springboot异步上传存储方法

xmd2e60i  于 2023-02-08  发布在  Spring
关注(0)|答案(1)|浏览(136)

我正在尝试使异步上传服务与 Spring 启动,这里是我的代码:

public ResponseEntity<?> save(MultipartFile[] files) {
    if (files.length == 0) {
        return ResponseEntity.badRequest().body("No files selected");
    }

    DigikyblikFileStorage storage = digikyblikFileStoragesService.getIdealStorage();
    UUID bucketUUID = UUID.randomUUID();

    asyncService.saveFiles(files, storage, bucketUUID);

    try {
        List<File> filesData = new ArrayList<>();

        for (MultipartFile file : files) {
            filesData.add(new File(file.getOriginalFilename(), file.getSize()));
        }

        BucketFilesRecord record = new BucketFilesRecord();
        record.setBucketUUID(bucketUUID);
        record.setStorageId(storage.getId());
        record.setFilesInfo(new ObjectMapper().writeValueAsString(filesData));
        bucketFilesRecordRepository.save(record);

        
    } catch (JsonProcessingException e) {
        logger.error("Error when setting files info for bucketUUID: " + bucketUUID, e);
        return ResponseEntity.internalServerError().body("Error when setting files info for bucketUUID: " + bucketUUID);
    } catch (IOException e) {
        logger.error("Error when getting bytes from multipart files for bucketUUID: " + bucketUUID, e);
    }

    return new ResponseEntity<>(new FilesUploadedResponse(bucketUUID), HttpStatus.OK);
}

以及:

@Async
public void saveFiles(MultipartFile[] files, DigikyblikFileStorage storage, UUID bucketUUID) {
    logger.info("Start storing files for bucketUUID: " + bucketUUID);

    Path filesPath = Paths.get(storage.getStoragePath() + java.io.File.separator + bucketUUID);

    try {
        Files.createDirectories(filesPath);
    } catch (IOException e) {
        logger.error("Couldn't create directories for bucketUUID: " + bucketUUID, e);
        return;
    }
    
    for (MultipartFile file : files) {
        Path path = Paths.get(filesPath + java.io.File.separator + file.getOriginalFilename());
        try {
            file.transferTo(path);
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

有时它工作得很好,但有时我得到这个错误:

java.nio.file.NoSuchFileException: /media/wedos-test/upload_814fc87f_9641_48be_adb4_c79f0111f11c_00000012.tmp

我知道为什么,它是因为Spring删除临时文件夹之前,文件事务完成,但我不知道这可以修复,一个解决方案是,一个可以读取字节,然后调用异步方法,所以临时目录不应该再需要了,但当我尝试用这个解决方案上传更大的文件,我当然得到内存错误。有人能帮我解决这个问题吗?谢谢!

g52tjvyc

g52tjvyc1#

我认为that answer的第二条评论可以帮助你,它说你可以在磁盘上创建自己的临时文件,并在需要的时候使用它,在这种情况下你不需要考虑内存。
看一下approach number 2,它建议使用带有自定义构造函数的MultiPartFile实现,然后在逻辑中使用它。

相关问题