Java将多部分文件转换为大文件的文件
我正在使用以下方法将MultipartFile转换为文件:Java将多部分文件转换为大文件的文件,java,spring,multipart,Java,Spring,Multipart,我正在使用以下方法将MultipartFile转换为文件: public File convert(MultipartFile file) throws IOException { File convFile = new File(file.getOriginalFilename()); convFile.createNewFile(); FileOutputStream fos = new FileOutputStream(convFile);
public 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;
}
这项工作很好,但对于大文件,我有一个例外:
java.lang.OutOfMemoryError: Java heap space
我添加了更多堆,但仍然有错误
那么有没有一种编程方法来解决这个问题呢?可能是在转换时将多部分文件分割成更小的块,但我不知道如何编写代码
任何帮助或建议都将不胜感激。多部分文件是否属于Spring的软件包
org.springframework.web.multipart
?如果是的话,你可以这样做
public File convert(MultipartFile file) throws IOException {
File convFile = new File(file.getOriginalFilename());
convFile.createNewFile();
try(InputStream is = file.getInputStream()) {
Files.copy(is, convFile.toPath());
}
return convFile;
}
下面的代码将帮助您将文件划分为块,然后进行聚合
try
{
file = new File(filePath.toString());
messageDigest = MessageDigest.getInstance("MD5");
checksum = getFileCheckSum(messageDigest, file);
fileInputStream = new FileInputStream(file);
int fileSize = (int) file.length();
fileChannel = fileInputStream.getChannel();
int numberOfChunks = (int) Math.ceil(fileChannel.size() / (double) chunkSize);
int totalpacket = numberOfChunks;
int totalFileSize = fileSize;
int read = 0;
while (numberOfChunks > 0)
{
System.out.println("file is :" + file + "checksum is:" + checksum);
fileSize -= read;
if (numberOfChunks > 1)
{
ByteBuffer bytebuffer = ByteBuffer.allocate(chunkSize);
read = fileChannel.read(bytebuffer);
bytebuffer.flip();
String content = new String();
if (bytebuffer.hasRemaining())
{
content = new String(bytebuffer.array(), Charset.forName("UTF-8"));
}
bytebuffer.clear();
}
else
{
String chunkData = new String();
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
fileChannel.read(byteBuffer);
chunkData = new String(byteBuffer.array(), Charset.forName("UTF-8"));
byteBuffer.clear();
}
numberOfChunks--;
}
}
catch (IOException e)
{
log.info(e);
}
catch (NoSuchAlgorithmException nsae)
{
log.info(nsae);
}
finally
{
try
{
fileInputStream.close();
fileChannel.close();
}
catch (IOException ioe)
{
log.info(ioe);
}
}
使用transferTo如何:
public File convert(MultipartFile file) throws IOException
{
File convFile = new File(file.getOriginalFilename());
file.transferTo(convFile);
return convFile;
}
file.getInputStream()
将返回流,这对您有帮助吗?MulipartFile应该有一个toFile(file)
方法用于此操作。新文件(file.getOriginalFilename())
。嗯,如果两个同时请求同时上传“untitled.pdf”,会发生什么情况?我想是各种各样的坏事吧。此外,恶意用户将有一个现场日。我个人很想尝试使用“C:\Win32\whatever”或“~/bash.rc”作为示例名称(不要这样做!永远不要相信用户提交的内容)@GPI实际上我们永远不会拥有两个同名文件,因为我会在文件末尾加上时间,如下所示:“untitle-09-10-2018-hh-mm-ss-ms.pdf”好的,很高兴知道。。。但您仍然有用户生成的前缀路径?这可能很危险。如果用户文件名包含“/”或“:”或“\”,该怎么办?我会将用户生成的名称视为元数据(如果没有必要,也可以完全删除它),并生成一个唯一的FS安全名称(例如Files.createXXXFile
family of methods)。它显示此错误无法解析此行Files上的方法副本(java.io.InputStream,java.io.FileOutputStream)。copy(…)发生异常时,流不会关闭。此处应使用try with resources(FileOutputStream fos=new FileOutputStream(convFile)
)。我不知道您从何处获取了文件。复制(InputStream,OutputStream)
,但输入流可能也应正确关闭(但这取决于库)@abdenaceurlicheheb这可能是个错误,OP的意思是来自Apache Commons IO或Guava的。@abdenaceurlicheheb文件。readAllBytes()
将所有字节读取到内存中,并可能导致OOME。您应该尝试从流中读取。此方法不会保存我得到的文件FileNotFoundExceptionCorry,那么您必须先添加create语句。create语句是什么意思?公共文件转换(MultipartFile file file)抛出IOException{file convFile=new file(file.getOriginalFilename());convFile.createNewFile();file.transferTo(convFile);return convFile;}我检查了api,createNewFile没有帮助。看起来重点可能是您的环境-您是否使用servlet 3.x api运行?