Скопировать файлы.tar.gz в папку

Я хочу скопировать содержимое файлов.tar.gz в папку 2, в ней около 20 файлов, а общий размер разархивированного файла будет>20 ГБ.
Я использовал 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.

3 ответа

Решение

Спасибо 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);
}

Надеюсь, я смогу сделать еще несколько оптимизаций, сделаю позже. большое спасибо

Кажется, что listFiles() распаковывает ваш gzip файл для того, чтобы иметь возможность сканировать через tar файл, чтобы получить все имена файлов, а затем cp(File, File) сканирует это снова, чтобы расположить поток на данном файле.

Я бы использовал Apache Commons Compress и выполнил итераторное сканирование входных потоков, примерно так:

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 для ArchiveInputStream#getNextEntry() а также ArchiveEntry для получения дополнительной информации.

Причиной проблемы с производительностью, с которой вы столкнулись, является то, что в формате файла TAR отсутствует центральный каталог. Но поскольку TrueZIP является виртуальной файловой системой и не может предсказать шаблон доступа клиентского приложения, при первом доступе он должен разархивировать весь файл TAR во временный каталог. Это то, что происходит в TFile.listFiles(). Затем вы копируете записи из временного каталога в целевые каталоги. Таким образом, в целом каждый входной байт будет прочитан или записан четыре раза.

Чтобы добиться максимальной производительности, у вас есть два варианта:

(а) Вы можете переключиться на формат файла ZIP и придерживаться API-интерфейса TrueZIP File *. ZIP-файлы имеют центральный каталог, поэтому их чтение не требует создания временных файлов.

(б) Вы можете обработать файл TAR.GZ как поток, как показано в npe. Затем я бы объединил это с java.util.zip.GZIPInputStream, потому что эта реализация основана на быстром C-коде. Я бы также использовал метод TrueZIP Streams.copy(InputStream, OuputStream), потому что он будет использовать многопоточность для действительно быстрого массового копирования.

Другие вопросы по тегам