Java 将.tar.gz文件复制到文件夹
我想将.tar.gz文件的内容复制到2个文件夹中,它有大约20个文件,总解压大小将>20GB。Java 将.tar.gz文件复制到文件夹,java,vfs,truezip,Java,Vfs,Truezip,我想将.tar.gz文件的内容复制到2个文件夹中,它有大约20个文件,总解压大小将>20GB。 我用Truezip做这个 TFile archive = new TFile(absoluteZipName); // archive with .tar.gz TFile[] archFiles = archive.listFiles(); // takes too much time for (TFile t : archFiles) { String fil
我用Truezip做这个
TFile archive = new TFile(absoluteZipName); // archive with .tar.gz
TFile[] archFiles = archive.listFiles(); // takes too much time
for (TFile t : archFiles) {
String fileName = t.getName();
if(fileName.endsWith(".dat"))
t.cp(new File(destination1+ t.getName()));
else if(fileName.endsWith(".txt")){
t.cp(new File(destination2+ t.getName()));
}
}
It takes 3 times above tar xzf command (untar linux) . Have any way to optimize this code for fast copying, memory not an issue.
The following code allows fast copying Thanks npe for the good advice.
(NB: I have no previledge to post the answe now that's why editing question itself)
InputStream is = new FileInputStream(absoluteZipName);
ArchiveInputStream input = new ArchiveStreamFactory()
.createArchiveInputStream(ArchiveStreamFactory.TAR, new GZIPInputStream(is));
ArchiveEntry entry;
while ((entry = input.getNextEntry()) != null) {
OutputStream outputFileStream=null;
if(entry.getName().endsWith(".dat")){
File outFile1= new File(destination1, entry.getName());
outputFileStream = new FileOutputStream(outFile1);
}
else if(entry.getName().endsWith(".txt")){
File outFile2= new File(destination2, entry.getName());
outputFileStream = new FileOutputStream(outFile2);
}
// use ArchiveEntry#getName() to do the conditional stuff...
IOUtils.copy(input, outputFileStream,10485760);
}
Is threading In file copy will reduce time..? In TZip didn't reduced as they already threading it. anyway I will try tomorrow and will let you Know.
似乎
listFiles()
解压您的gzip
文件,以便能够扫描tar
文件以获得所有文件名,然后cp(file,file)
再次扫描以将流定位到给定文件上
我要做的是在inputstreams上使用和执行类似迭代器的扫描,有点像这样:
InputStream is = new FileInputStream("/path/to/my/file");
ArchiveInputStream input = new ArchiveStreamFactory()
.createArchiveInputStream(ArchiveStreamFactory.TAR, new GZIPInputStream(is));
ArchiveEntry entry;
while ((entry = input.getNextEntry()) != null) {
// use ArchiveEntry#getName() to do the conditional stuff...
}
阅读javadoc了解更多信息。您看到的性能问题的原因是TAR文件格式缺少中心目录。但是,由于TrueZIP是一个虚拟文件系统,它无法预测客户端应用程序的访问模式,因此它必须在第一次访问时将整个TAR文件解压缩到一个临时目录。这是在TFile.listFiles()上发生的情况。然后将条目从临时目录复制到目标目录。因此,总的来说,每个条目字节将被读取或写入四次 要获得最佳性能,您有两种选择: (a) 您可以切换到ZIP文件格式并坚持使用TrueZIP file*API。ZIP文件有一个中心目录,因此读取它们不需要创建临时文件
(b) 您可以将TAR.GZ文件作为流进行处理,如npe所示。然后,我将把它与java.util.zip.GZIPInputStream结合起来,因为该实现基于fast C代码。我还将使用TrueZIP的Streams.copy(InputStream,OutStream)方法,因为它将使用多线程进行真正快速的批量复制。感谢npe,这是我最后一次使用它,无论以何种方式,它比tar xzf花费的时间都要少。最后的代码片段如下
InputStream is = new FileInputStream(absoluteZipName);
ArchiveInputStream input = new ArchiveStreamFactory()
.createArchiveInputStream(ArchiveStreamFactory.TAR, new GZIPInputStream(is));
ArchiveEntry entry;
while ((entry = input.getNextEntry()) != null) {
OutputStream outputFileStream=null;
if(entry.getName().endsWith(".dat")){
File outFile1= new File(destination1, entry.getName());
outputFileStream = new FileOutputStream(outFile1);
}
else if(entry.getName().endsWith(".txt")){
File outFile2= new File(destination2, entry.getName());
outputFileStream = new FileOutputStream(outFile2);
}
// use ArchiveEntry#getName() to do the conditional stuff...
IOUtils.copy(input, outputFileStream,10485760);
}
希望我能做更多的优化,以后会做的。
非常感谢分两步完成吗?tar-xzvf./some/tmp/destination+2倍于扩展上的“mv”命令过滤?还是必须使用java?在这种情况下,我认为您不能对其进行太多优化。我先尝试了这个…,我需要先解压,然后再解压。也占用了平常时间的两倍。编辑了答案,给出了一个示例,说明如何通过
gzip输入流
将该流直接传递给commons compress
。这样,一切都应该是一个一步的过程。您也可以使用一个,而不是JDK实现。我将在下一个帖子中发布修改后的代码我很快就没有previledge帖子的答案了,所以我编辑了这个问题谢谢npe的宝贵建议哦,你不必发布答案,你可以接受我的;-)