Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.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 将.tar.gz文件复制到文件夹_Java_Vfs_Truezip - Fatal编程技术网

Java 将.tar.gz文件复制到文件夹

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

我想将.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 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的宝贵建议哦,你不必发布答案,你可以接受我的;-)