我如何在Java中提取一个tar文件?

如何在Java中提取tar(或tar.gz或tar.bz2)文件?

注意:此function后来通过另一个项目Apache Commons Compress发布,如另一个答案中所述。 这个答案已经过时了。


我没有直接使用tar API,但tar和bzip2在Ant中实现; 你可以借用他们的实现,或者用Ant来做你所需要的。

Gzip是Java SE的一部分 (我猜Ant实现遵循相同的模型)。

GZIPInputStream只是一个InputStream装饰器。 例如,可以将一个FileInputStream封装在GZIPInputStream并以与使用任何InputStream相同的方式使用它:

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

(请注意,GZIPInputStream具有自己的内部缓冲区,因此将FileInputStream包装在BufferedInputStream可能会降低性能。)

您可以使用Apache Commons Compress库执行此操作。 您可以从http://mvnrepository.com/artifact/org.apache.commons/commons-compress/1.2下载1.2版本。;

这里有两种方法:一种是解压缩一个文件,另一种解压缩文件。 因此,对于文件<文件名> tar.gz,您需要先解压缩,然后解压缩。 请注意,tar归档文件也可能包含文件夹,这些文件夹需要在本地文件系统上创build。

请享用。

 /** 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支持tar作为虚拟文件系统 ,它支持这样的URL tar:gz: http://anyhost/dir/mytar.tar.gz!/mytar.tar!/path/in/tar/README.txt

TrueZip或其后继者TrueVFS也是这样做的…它也可以从Maven Central获得。

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

相关性:

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

我刚刚尝试了一堆build议的库(TrueZip,Apache压缩),但没有运气。

以下是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(); } } 

而maven的依赖:

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

除了gzip和bzip2之外, Apache Commons Compress API还有tar支持,最初基于ICE Engineering Java Tar Package ,这是API和独立工具。

如何使用这个API的tar文件,这另外一个包含在Ant为BZIP2和标准的一个为GZIP?