Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中更快地合并大文件部分_Java_Filesystems - Fatal编程技术网

在java中更快地合并大文件部分

在java中更快地合并大文件部分,java,filesystems,Java,Filesystems,我正在编写一个JavaREST服务来支持大文件部分的并行上传。我在单独的文件中编写这些部分,并使用文件通道将它们合并。我有一个在Golang中实现的示例,它也执行相同的操作,但是当它合并各个部分时,它不需要时间。当我使用文件通道或从一个流读取并写入最终文件时,需要很长时间。我认为不同之处在于,Golang能够保持磁盘上的数据不变,只需通过不移动数据来合并它们。有没有什么方法可以在java中实现同样的功能? 这是我合并部件的代码,我对所有部件循环使用此方法: private void mergeF

我正在编写一个JavaREST服务来支持大文件部分的并行上传。我在单独的文件中编写这些部分,并使用文件通道将它们合并。我有一个在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();
        }
    }

}
向各国转让的文件:

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

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

我建议的一个小优化是在模式下打开文件

位置的提升和数据的写入是否在单个原子操作中完成取决于系统

除此之外,你可能还得想办法解决这个问题。例如,首先创建一个足够大的连续文件


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

操作系统和文件系统类型是否与此问题相关?服务器是fedora 24。我不确定文件系统。我正在将文件传输到HDD、SSD和网络位置。因此,我尝试了几种组合,并得出结论,其操作系统和文件系统使I/O操作变慢或变快。我尝试在USB端口上连接NTFS和ext4格式的HDD,并在25秒内得到相同的结果,用于合并1GB文件的30个部分。当我在我的windows机器上的HDD上尝试同样的方法时,不到10秒。我现在正在阅读有关文件系统和操作系统如何管理I/O的文章。如果有人有好的链接可以阅读,我将不胜感激。另外,我查看了GoLang示例,它有一个技巧,它将文件的一部分合并到最终罚款,因为该部分到达服务器,而不是在最后。将此标记为已回答,因为我使用了与我所发布的相同的方法。合并的时间取决于媒体本身。java的NIO在使用channel的transferto方法进行合并方面做得很好,以避免上下文切换和缓冲区复制。我需要考虑客户端-服务器连接LAN/WAN和目标媒体类型来使用我的设置,以充分利用可用的内容,谢谢!