在Java中,拼接两个超过1.5GB的大文件,最高效(最快)的方法是什么?

10

我使用这里的技术,并在70秒内将两个1.5GB文件连接起来。

http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly

我的代码使用了FileChannels、内存映射和8KB缓冲区大小的ByteBuffers。

我该如何提高速度?

File file = new File(binDirectory + "/donjon.avi");
File oFile = new File(binDirectory + "/donjon2.avi");

FileInputStream is = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(oFile);
FileChannel f1 = is.getChannel();
FileChannel f2 = fos.getChannel();

f2.transferFrom(f1, 0, f1.size());
f2.transferFrom(f1, f1.size(), f1.size());

f2.close();
f1.close();

2
调整缓冲区大小,可能会/可能不会提高速度。 - hd1
2
仅8kB的缓冲区?对于如此大的文件,请尝试使用1MB到10MB的范围。 - Njol
1
这个Java问题是否与部署在服务器上的Java应用程序(1个消费者)相关,还是与部署在桌面上的Java应用程序(多个消费者)相关?如果这是部署在服务器上的应用程序,调用外部命令来连接两个文件会更快吗?使用类似*nix操作系统中的cat命令如何?http://www.linfo.org/cat.html cat file1 file2 file3 > file4 - Developer Marius Žilėnas
这只是一个关于Java编程中限制的好奇问题。感谢您的评论,但我不想使用外部命令。 - Danny Rancher
您现在正在以20 MB/sec的速率传输数据。根据您使用的驱动器,它可能会受到I/O速度的限制,而不是Java。您可以通过使用“cat”制作连接文件来轻松验证最佳速度,看看需要多长时间。 - StaxMan
显示剩余4条评论
1个回答

13

试一下这个

    FileChannel c1 = new FileInputStream("1").getChannel();
    FileChannel c2 = new FileOutputStream("2", true).getChannel();
    c2.transferFrom(c1, c2.size(), c1.size());

javadoc称FileChannel.transferFrom比简单循环从此通道读取并写入目标通道的方法潜在地更有效率。许多操作系统可以直接将字节从文件系统缓存传输到目标通道,而无需实际复制它们。


确实,手动复制文件的字节到另一个文件会更快。谢谢。我尝试修改它以在输出文件中复制第一个文件的内容,但没有成功。我的代码在我的问题中。 - Danny Rancher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接