在Java中更快地合并大文件零件



我正在编写一个Java Rest服务,以支持大型文件的部分的并行上传。我正在将这些零件写入单独的文件中,并使用文件频道合并它们。我在Golang中实现了一个样本,它的作用相同,但是当它合并零件时,它不需要时间。当我使用文件频道或从一个流中读取并写入最终文件时,需要很长时间。我认为的区别是,Golang具有将数据保持在原样的能力,并且只是通过不移动数据而合并它们。有什么办法可以在Java中做同样的事情? 这是我合并零件的代码,我循环使用此方法:

private void mergeFileUsingChannel(String destinationPath, String sourcePath, long partSize, long offset) throws Exception{
    FileChannel outputChannel = null;
    FileChannel inputChannel = null;
    try{
        outputChannel = new FileOutputStream(new File(destinationPath)).getChannel();
        outputChannel.position(offset);
        inputChannel = new FileInputStream(new File(sourcePath)).getChannel();
        inputChannel.transferTo(0, partSize, outputChannel);
    }catch(Exception e){
        e.printStackTrace();
    }
    finally{
        if(inputChannel != null)
            inputChannel.close();
        if(outputChannel != null){
            outputChannel.close();
        }
    }
}

filechannel transferTo的文档状态:

"许多操作系统可以直接将字节从文件系统缓存传输到目标通道而无需实际复制它们。"

因此,您编写的代码是正确的,并且您看到的效率低下可能与基础文件系统类型有关。

我可以建议的一个小优化是在附加模式下打开文件。

"在单个原子操作中的位置的进步和数据的写入是否与系统有关"

除此之外,您可能还必须考虑一种解决问题的方法。例如,通过创建足够大的连续文件作为第一步。


编辑:我还注意到您没有明确关闭FileOutputStream。最好坚持下去并关闭它,以便所有文件描述符都关闭。

最新更新