How do I extract a tar file in Java?
Note: This functionality was later published through a separate project, Apache Commons Compress, as described in another answer. This answer is out of date.
I haven't used a tar API directly, but tar and bzip2 are implemented in Ant; you could borrow their implementation, or possibly use Ant to do what you need.
Gzip is part of Java SE (and I'm guessing the Ant implementation follows the same model).
GZIPInputStream
is just an InputStream
decorator. You can wrap, for example, a FileInputStream
in a GZIPInputStream
and use it in the same way you'd use any InputStream
:
InputStream is = new GZIPInputStream(new FileInputStream(file));
(Note that the GZIPInputStream has its own, internal buffer, so wrapping the FileInputStream
in a BufferedInputStream
would probably decrease performance.)
You can do this with the Apache Commons Compress library. You can download the 1.2 version from http://mvnrepository.com/artifact/org.apache.commons/commons-compress/1.2.
Here are two methods: one that unzips a file and another one that untars it. So, for a file <fileName>tar.gz, you need to first unzip it and after that untar it. Please note that the tar archive may contain folders as well, case in which they need to be created on the local filesystem.
Enjoy.
/** 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;
}