MultipartFile问题,无法转换为文件

时间:2019-11-05 19:54:55

标签: java spring rest spring-boot spring-mvc

我正在尝试上传1 GB以上的文件,我正在使用Spring Boot。

我尝试使用下面的代码,但出现内存不足错误。

public void uploadFile(MultipartFile file) throws IOException {
        try {       
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
            requestFactory.setBufferRequestBody(false);
            restTemplate.setRequestFactory(requestFactory);

            String uploadFile= restTemplate.exchange(url, HttpMethod.POST,
                new HttpEntity<>(new FileSystemResource(convert(file)), headers), String.class).getBody();

        } catch (Exception e) {
            throw new RuntimeException("Exception Occured", e);
        }
    }


    private static File convert(MultipartFile file) throws IOException {
        File convFile = new File(file.getOriginalFilename());
        convFile.createNewFile();
        FileOutputStream fos = new FileOutputStream(convFile);
        fos.write(file.getBytes());
        fos.close();
        return convFile;    
    }

我面临的主要问题是,我无法将MultipartFile转换为java.io.File。

我什至尝试将FileSystemResource替换为ByteArrayResource,但仍然出现OOM错误。

我什至也尝试过使用以下代码:

private static File convert(MultipartFile file) throws IOException {
        CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
        FileItem fileItem = commonsMultipartFile.getFileItem();
        DiskFileItem diskFileItem = (DiskFileItem) fileItem;
        String absPath = diskFileItem.getStoreLocation().getAbsolutePath();
        File file = new File(absPath);  
    }

但是上面的代码段却出现了以下异常:

  

org.springframework.web.multipart.commons.CommonsMultipartFile无法   强制转换为org.springframework.web.multipart.MultipartFile

  1. 有人可以告诉我如何将MultipartFile转换为java.io.File吗?

  2. 还有什么比FileSystemResource更好的方法吗?bcoz在上载之前,每次必须在服务器中创建新文件。如果文件大于1GB,则必须在服务器端创建另一个1GB的新文件,并且必须再次手动删除该文件,我个人不喜欢这种方法。

1 个答案:

答案 0 :(得分:3)

getBytes()试图将整个字节数组加载到内存中,这导致OOM您需要做的是流传输文件并将其写出。

尝试以下操作:

private static Path convert(MultipartFile file) throws IOException {
  Path newFile = Paths.get(file.getOriginalFilename());
  try(InputStream is = file.getInputStream();
     OutputStream os = Files.newOutputStream(newFile))) {
     byte[] buffer = new byte[4096];
     int read = 0;
     while((read = is.read(buffer)) > 0) {
       os.write(buffer,0,read);
     }
  }
  return newFile;  
}

我将您的方法更改为返回Path包中的File而不是java.nio。该软件包比java.io更受青睐,因为它已经过优化。

如果确实需要File对象,则可以调用newFile.toFile()

由于它返回了Path对象,因此一旦写出文件,您就可以使用java.nio.file.Files类将文件重新定位到您的首选目录

private static void relocateFile(Path original, Path newLoc) throws IOException {
  if(Files.isDirectory(newLoc)) {
    newLoc = newLoc.resolve(original.getFileName());
  }
  Files.move(original, newLoc);
}