web-dev-qa-db-ja.com

Javaでtarファイルを作成します

Javaを使用して、フォルダをtarファイルに(プログラムで)圧縮します。それを行うには、オープンソースまたはライブラリが必要だと思います。しかし、そのような方法は見つかりません。

または、Zipファイルを作成し、その拡張名を.tarに変更できますか?

だれでもそれをするために図書館を提案できますか?ありがとう!

jtar-Java Tarライブラリ を使用できます。

彼らのサイトから取られた:

JTarはシンプルなJava Tarライブラリであり、IOストリームを使用してtarファイルを簡単に作成および読み取ることができます。APIは非常に使いやすく、類似していますJava.util.Zipパッケージに。

彼らのサイトからの例:

   // Output file stream
   FileOutputStream dest = new FileOutputStream( "c:/test/test.tar" );

   // Create a TarOutputStream
   TarOutputStream out = new TarOutputStream( new BufferedOutputStream( dest ) );

   // Files to tar
   File[] filesToTar=new File[2];
   filesToTar[0]=new File("c:/test/myfile1.txt");
   filesToTar[1]=new File("c:/test/myfile2.txt");

   for(File f:filesToTar){
      out.putNextEntry(new TarEntry(f, f.getName()));
      BufferedInputStream Origin = new BufferedInputStream(new FileInputStream( f ));

      int count;
      byte data[] = new byte[2048];
      while((count = Origin.read(data)) != -1) {
         out.write(data, 0, count);
      }

      out.flush();
      Origin.close();
   }

   out.close();
16
Marcelo

Apache Commons Compress を見てみます。

途中にある例 この例のページ は、tarの例を示しています。

TarArchiveEntry entry = new TarArchiveEntry(name);
entry.setSize(size);
tarOutput.putArchiveEntry(entry);
tarOutput.write(contentOfEntry);
tarOutput.closeArchiveEntry();
30

.tarアーカイブファイルは圧縮されません。 gzipのようにファイル圧縮を実行し、.tar.gzのようなものに変換する必要があります。

ディレクトリをアーカイブするだけの場合は、次をご覧ください。

8
tskuzzy

この問題を解決するために、次のコードを作成しました。このコードは、組み込むファイルのいずれかがすでにtarファイルに存在するかどうかを確認し、そのエントリを更新します。後で存在しない場合は、アーカイブの最後に追加します。

import org.Apache.commons.compress.archivers.ArchiveEntry;
import org.Apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.Apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.Apache.commons.compress.archivers.tar.TarArchiveOutputStream;

public class TarUpdater {

        private static final int buffersize = 8048;

        public static void updateFile(File tarFile, File[] flist) throws IOException {
            // get a temp file
            File tempFile = File.createTempFile(tarFile.getName(), null);
            // delete it, otherwise you cannot rename your existing tar to it.
            if (tempFile.exists()) {
                tempFile.delete();
            }

            if (!tarFile.exists()) {
                tarFile.createNewFile();
            }

            boolean renameOk = tarFile.renameTo(tempFile);
            if (!renameOk) {
                throw new RuntimeException(
                        "could not rename the file " + tarFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
            }
            byte[] buf = new byte[buffersize];

            TarArchiveInputStream tin = new TarArchiveInputStream(new FileInputStream(tempFile));

            OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(tarFile.toPath()));
            TarArchiveOutputStream tos = new TarArchiveOutputStream(outputStream);
            tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);

            //read  from previous  version of  tar  file
            ArchiveEntry entry = tin.getNextEntry();
            while (entry != null) {//previous  file  have entries
                String name = entry.getName();
                boolean notInFiles = true;
                for (File f : flist) {
                    if (f.getName().equals(name)) {
                        notInFiles = false;
                        break;
                    }
                }
                if (notInFiles) {
                    // Add TAR entry to output stream.
                    if (!entry.isDirectory()) {
                        tos.putArchiveEntry(new TarArchiveEntry(name));
                        // Transfer bytes from the TAR file to the output file
                        int len;
                        while ((len = tin.read(buf)) > 0) {
                            tos.write(buf, 0, len);
                        }
                    }
                }
                entry = tin.getNextEntry();
            }
            // Close the streams
            tin.close();//finished  reading existing entries 
            // Compress new files

            for (int i = 0; i < flist.length; i++) {
                if (flist[i].isDirectory()) {
                    continue;
                }
                InputStream fis = new FileInputStream(flist[i]);
                TarArchiveEntry te = new TarArchiveEntry(flist[i],flist[i].getName());
                //te.setSize(flist[i].length());
                tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
                tos.setBigNumberMode(2);
                tos.putArchiveEntry(te); // Add TAR entry to output stream.

                // Transfer bytes from the file to the TAR file
                int count = 0;
                while ((count = fis.read(buf, 0, buffersize)) != -1) {
                    tos.write(buf, 0, count);
                }
                tos.closeArchiveEntry();
                fis.close();
            }
            // Complete the TAR file
            tos.close();
            tempFile.delete();
        }
    }

Gradleを使用する場合は、次の依存関係を使用します。

compile group: 'org.Apache.commons', name: 'commons-compress', version: '1.+'

私はorg.xeustechnologies:jtar:1.1も試しましたが、パフォーマンスはorg.Apache.commons:commons-compress:1.12が提供するパフォーマンスを大幅に下回っています。

異なる実装を使用したパフォーマンスに関するメモ:

Java 1.8 Zipを使用して10回圧縮する:
-Java.util.Zip.ZipEntry;
-Java.util.Zip.ZipInputStream;
-Java.util.Zip.ZipOutputStream;

[2016-07-19 19:13:11]以前
[2016-07-19 19:13:18]後
7秒

jtarを使用して10回ターリング:
-org.xeustechnologies.jtar.TarEntry;
-org.xeustechnologies.jtar.TarInputStream;
-org.xeustechnologies.jtar.TarOutputStream;

[2016-07-19 19:21:23]以前
[2016-07-19 19:25:18]後
3分55秒

Cygwin/usr/bin/tarへのシェル呼び出し-10回
[2016-07-19 19:33:04]以前
[2016-07-19 19:33:14]後
14秒

org.Apache.commons.compressを使用して100回(100回)ターリング:
-org.Apache.commons.compress.archivers.ArchiveEntry;
-org.Apache.commons.compress.archivers.tar.TarArchiveEntry;
-org.Apache.commons.compress.archivers.tar.TarArchiveInputStream;
-org.Apache.commons.compress.archivers.tar.TarArchiveOutputStream;

[2016-07-19 23:04:45]以前
[2016-07-19 23:04:48]後
3秒

org.Apache.commons.compressを使用して1000(千)回のテスト:
[2016-07-19 23:10:28]以前
[2016-07-19 23:10:48]後
20秒

4
aprodan