Pregunta

¿Cómo puedo extracto de alquitrán (o tar.gz o alquitrán.bz2) archivo en Java?

¿Fue útil?

Solución

Nota: Esta funcionalidad fue publicado más tarde a través de un proyecto independiente, Apache Commons Comprimir, como se describe en otra respuesta. Esta respuesta está fuera de fecha.


No he utilizado un tar de la API directamente, pero alquitrán y bzip2 se implementan en la Hormiga;usted puede pedir prestado de su aplicación, o, posiblemente, el uso de la Hormiga para hacer lo que usted necesita.

Gzip es parte de Java SE (y supongo que la de la Hormiga de la aplicación sigue el mismo modelo).

GZIPInputStream es sólo un InputStream decorador.Usted puede ajustar, por ejemplo, un FileInputStream en un GZIPInputStream y el uso que de la misma manera que utilizaría cualquier InputStream:

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

(Tenga en cuenta que el GZIPInputStream tiene su propio búfer interno, de manera de envolver el FileInputStream en un BufferedInputStream probablemente disminuir el rendimiento.)

Otros consejos

Puede hacer esto con la biblioteca Apache Commons Compress. Puede descargar la versión 1.2 desde http://mvnrepository.com/artifact/ org.apache.commons / commons-compress / 1.2 .

Aquí hay dos métodos: uno que descomprime un archivo y otro que lo descomprime. Entonces, para un archivo < fileName > tar.gz, primero debe descomprimirlo y luego descomprimirlo. Tenga en cuenta que el archivo tar también puede contener carpetas, en caso de que necesiten crearse en el sistema de archivos local.

Disfruta.

/** 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;
}

Apache Commons VFS admite tar como un sistema de archivos virtual , que admite URL como esta tar:gz:http://anyhost/dir/mytar.tar.gz!/mytar.tar!/path/in/tar/README.txt

TrueZip o su sucesor TrueVFS hace lo mismo ... también está disponible en Maven Central.

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

Dependencia:

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

Acabo de probar algunas de las librerías sugeridas (TrueZip, Apache Compress), pero no tuve suerte.

Aquí hay un ejemplo con 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();
    }
}

Y la dependencia de Maven:

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

Además de gzip y bzip2, Apache Commons Compress API también tiene soporte de tar, originalmente basado en ICE Engineering Java Tar Package , que es una API y una herramienta independiente.

¿Qué pasa con el uso de esta API para archivos tar, esto otro incluido dentro de Ant para BZIP2 y el estándar para GZIP?

Aquí hay una versión basada en esta respuesta anterior de Dan Borza que usa Apache Commons Compress y Java NIO (es decir, Path en lugar de File). También realiza la descompresión y descompresión en una secuencia, por lo que no hay creación de archivos intermedios.

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();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top