我正在尝试上传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
有人可以告诉我如何将MultipartFile转换为java.io.File吗?
还有什么比FileSystemResource
更好的方法吗?bcoz在上载之前,每次必须在服务器中创建新文件。如果文件大于1GB,则必须在服务器端创建另一个1GB的新文件,并且必须再次手动删除该文件,我个人不喜欢这种方法。
答案 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);
}