it-swarm.com.de

Wie extrahiere ich eine Tar-Datei in Java?

Wie extrahiere ich eine tar- (oder tar.gz- oder tar.bz2-) Datei in Java?

60
skiphoppy

Hinweis: Diese Funktionalität wurde später über ein separates Projekt veröffentlicht, Apache Commons Compress, as beschrieben in einer anderen Antwort. Diese Antwort lautet veraltet.


Ich habe keine direkte tar-API verwendet, aber tar und bzip2 sind in Ant implementiert. Sie können die Implementierung ausleihen oder Ant verwenden, um das zu tun, was Sie benötigen.

Gzip ist Teil von Java SE (und ich vermute, die Ant-Implementierung folgt demselben Modell).

GZIPInputStream ist nur ein InputStream Dekorateur. Sie können beispielsweise ein FileInputStream in ein GZIPInputStream einwickeln und es so verwenden, wie Sie jedes InputStream verwenden würden:

InputStream is = new GZIPInputStream(new FileInputStream(file));

(Beachten Sie, dass der GZIPInputStream über einen eigenen internen Puffer verfügt. Wenn Sie also FileInputStream in BufferedInputStream einschließen, wird die Leistung wahrscheinlich beeinträchtigt.)

19
erickson

Sie können dies mit der Apache Commons Compress-Bibliothek tun. Sie können die Version 1.2 von http://mvnrepository.com/artifact/org.Apache.commons/commons-compress/1.2 herunterladen.

Hier sind zwei Methoden: Eine, die eine Datei dekomprimiert, und eine andere, die sie dekomprimiert. Also, für eine Datei <fileName> tar.gz müssen Sie sie zuerst entpacken und danach entpacken. Bitte beachten Sie, dass das tar-Archiv auch Ordner enthalten kann, in denen sie auf dem lokalen Dateisystem erstellt werden müssen.

Genießen.

/** Untar an input file into an output file.

 * The output file is created in the output folder, having the same name
 * as the input file, minus the '.tar' extension. 
 * 
 * @param inputFile     the input .tar file
 * @param outputDir     the output directory file. 
 * @throws IOException 
 * @throws FileNotFoundException
 *  
 * @return  The {@link List} of {@link File}s with the untared content.
 * @throws ArchiveException 
 */
private static List<File> unTar(final File inputFile, final File outputDir) throws FileNotFoundException, IOException, ArchiveException {

    LOG.info(String.format("Untaring %s to dir %s.", inputFile.getAbsolutePath(), outputDir.getAbsolutePath()));

    final List<File> untaredFiles = new LinkedList<File>();
    final InputStream is = new FileInputStream(inputFile); 
    final TarArchiveInputStream debInputStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is);
    TarArchiveEntry entry = null; 
    while ((entry = (TarArchiveEntry)debInputStream.getNextEntry()) != null) {
        final File outputFile = new File(outputDir, entry.getName());
        if (entry.isDirectory()) {
            LOG.info(String.format("Attempting to write output directory %s.", outputFile.getAbsolutePath()));
            if (!outputFile.exists()) {
                LOG.info(String.format("Attempting to create output directory %s.", outputFile.getAbsolutePath()));
                if (!outputFile.mkdirs()) {
                    throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
                }
            }
        } else {
            LOG.info(String.format("Creating output file %s.", outputFile.getAbsolutePath()));
            final OutputStream outputFileStream = new FileOutputStream(outputFile); 
            IOUtils.copy(debInputStream, outputFileStream);
            outputFileStream.close();
        }
        untaredFiles.add(outputFile);
    }
    debInputStream.close(); 

    return untaredFiles;
}

/**
 * Ungzip an input file into an output file.
 * <p>
 * The output file is created in the output folder, having the same name
 * as the input file, minus the '.gz' extension. 
 * 
 * @param inputFile     the input .gz file
 * @param outputDir     the output directory file. 
 * @throws IOException 
 * @throws FileNotFoundException
 *  
 * @return  The {@File} with the ungzipped content.
 */
private static File unGzip(final File inputFile, final File outputDir) throws FileNotFoundException, IOException {

    LOG.info(String.format("Ungzipping %s to dir %s.", inputFile.getAbsolutePath(), outputDir.getAbsolutePath()));

    final File outputFile = new File(outputDir, inputFile.getName().substring(0, inputFile.getName().length() - 3));

    final GZIPInputStream in = new GZIPInputStream(new FileInputStream(inputFile));
    final FileOutputStream out = new FileOutputStream(outputFile);

    IOUtils.copy(in, out);

    in.close();
    out.close();

    return outputFile;
}
67
Dan Borza

Apache Commons VFS unterstützt tar als virtuelles Dateisystem, die URLs wie diese unterstützen tar:gz:http://anyhost/dir/mytar.tar.gz!/mytar.tar!/path/in/tar/README.txt

TrueZip oder sein Nachfolger TrueVFS macht dasselbe ... es ist auch von Maven Central erhältlich.

12
Jörg
Archiver archiver = ArchiverFactory.createArchiver("tar", "gz");
archiver.extract(archiveFile, destDir);

Abhängigkeit:

 <dependency>
        <groupId>org.rauschig</groupId>
        <artifactId>jarchivelib</artifactId>
        <version>0.5.0</version>
</dependency>
10
D3iv

Ich habe gerade ein paar der vorgeschlagenen Bibliotheken (TrueZip, Apache Compress) ausprobiert, aber kein Glück.

Hier ist ein Beispiel mit Apache Commons VFS:

FileSystemManager fsManager = VFS.getManager();
FileObject archive = fsManager.resolveFile("tgz:file://" + fileName);

// List the children of the archive file
FileObject[] children = archive.getChildren();
System.out.println("Children of " + archive.getName().getURI()+" are ");
for (int i = 0; i < children.length; i++) {
    FileObject fo = children[i];
    System.out.println(fo.getName().getBaseName());
    if (fo.isReadable() && fo.getType() == FileType.FILE
        && fo.getName().getExtension().equals("nxml")) {
        FileContent fc = fo.getContent();
        InputStream is = fc.getInputStream();
    }
}

Und die Abhängigkeit der Maven:

    <dependency>
      <groupId>commons-vfs</groupId>
      <artifactId>commons-vfs</artifactId>
      <version>1.0</version>
    </dependency>
7
Renaud

Zusätzlich zu gzip und bzip2 unterstützt Apache Commons Compress API auch tar, ursprünglich basierend auf ICE Engineering Java Tar Package , also API und eigenständiges Tool.

6
Jörg

Was ist mit diesem API für TAR-Dateien, dieses andere in Ant für BZIP2 und das Standard für GZIP?

4

Hier ist eine Version basierend auf diese frühere Antwort von Dan Borza, die Apache Commons Compress und Java NIO (dh Pfad statt Datei) verwendet. Es wird auch das Dekomprimieren und Dekomprimieren in einem Stream durchgeführt, sodass keine Zwischendateien erstellt werden müssen.

public static void unTarGz( Path pathInput, Path pathOutput ) throws IOException {
    TarArchiveInputStream tararchiveinputstream =
        new TarArchiveInputStream(
            new GzipCompressorInputStream(
                new BufferedInputStream( Files.newInputStream( pathInput ) ) ) );

    ArchiveEntry archiveentry = null;
    while( (archiveentry = tararchiveinputstream.getNextEntry()) != null ) {
        Path pathEntryOutput = pathOutput.resolve( archiveentry.getName() );
        if( archiveentry.isDirectory() ) {
            if( !Files.exists( pathEntryOutput ) )
                Files.createDirectory( pathEntryOutput );
        }
        else
            Files.copy( tararchiveinputstream, pathEntryOutput );
    }

    tararchiveinputstream.close();
}
0
Wade Walker