Java将多部分文件转换为大文件的文件

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);

我正在使用以下方法将MultipartFile转换为文件:

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运行?