1 package org.gffs.compression;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.util.Iterator;
9 import org.apache.commons.compress.archivers.ArchiveEntry;
10 import org.apache.commons.compress.archivers.ArchiveOutputStream;
11 import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
12 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
13 import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
14 import org.apache.commons.io.FileUtils;
15 import org.apache.commons.io.IOUtils;
16 import org.apache.commons.io.filefilter.IOFileFilter;
17 import org.apache.commons.io.filefilter.TrueFileFilter;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
23 static private Log _logger = LogFactory.getLog(PackTar.class);
26 * returns the "longName" with the "prefix" stripped off the front. if the name doesn't contain the prefix, then an error is thrown.
28 public static String stripOutPrefix(String prefix, String longName) throws IOException
30 int indy = longName.indexOf(prefix, 0);
32 throw new IOException("failure to find prefix in string, prefix=" + prefix + " and string=" + longName);
33 return longName.substring(indy + prefix.length());
37 * adds the file pointed at by "source" to the archive in "tarOut" as a compressed file. if "source" is a directory, then the directory is
38 * recursed and added. the names in the archive will be stripped of the "prefix" string before being added to the archive; for example, if
39 * the source path "/home/fred/wumpus" and the prefix string is "/home/fred/", then the files in the archive will be named "wumpus/A",
42 public static void compressArchive(ArchiveOutputStream tarOut, String prefix, File source) throws IOException
44 _logger.debug("entered into compress archive on source " + source + " prefix " + prefix + " and tarout " + tarOut);
46 if (!source.exists()) {
47 // Don't unpack into an existing directory.
48 String msg = "Directory " + source.getAbsolutePath() + " doesn't exist yet. Cannot pack.";
50 throw new IOException(msg);
53 // traverse the whole tree of the directory (or just write this directly if it's a file).
54 if (source.isFile()) {
55 String choppedName = stripOutPrefix(prefix, source.getPath());
56 if (_logger.isDebugEnabled())
57 _logger.debug("adding a file to the archive (chopped): " + choppedName);
58 ArchiveEntry f = tarOut.createArchiveEntry(source, choppedName);
59 tarOut.putArchiveEntry(f);
60 IOUtils.copy(new FileInputStream(source), tarOut);
61 tarOut.closeArchiveEntry();
62 } else if (source.isDirectory()) {
63 // traverse the directory tree at just this height and add everything recursively.
65 if (_logger.isDebugEnabled())
66 _logger.debug("iterating over a directory to add its contents to the archive: " + source);
68 Iterator<File> spidey = FileUtils.iterateFiles(source, new IOFileFilter()
71 public boolean accept(File arg0)
77 public boolean accept(File arg0, String arg1)
81 }, TrueFileFilter.INSTANCE);
84 while (spidey.hasNext()) {
87 if (_logger.isTraceEnabled())
88 _logger.debug("recursing on item: " + item);
90 compressArchive(tarOut, prefix, item);
93 String msg = "source is not a file or directory although it exists. unknown how to process.";
95 throw new IOException(msg);
101 * returns the same string as presented, but ensures that the last character will be a directory separator (/).
103 public static String findAppropriatePrefix(String toChop)
105 if (toChop.endsWith("/"))
106 return toChop; // already ready.
108 return toChop + "/"; // add a slash on the end.
111 public synchronized static void compressTarGZ(File tarFile, File dest) throws IOException
113 TarArchiveOutputStream tarOut = new TarArchiveOutputStream(new GzipCompressorOutputStream(new FileOutputStream(tarFile)));
114 compressArchive(tarOut, findAppropriatePrefix(dest.getPath()), dest);
118 public synchronized static void compressTar(File tarFile, File dest) throws IOException
120 TarArchiveOutputStream tarOut = new TarArchiveOutputStream(new FileOutputStream(tarFile));
121 compressArchive(tarOut, findAppropriatePrefix(dest.getPath()), dest);
125 public synchronized static void compressZip(File zipFile, File dest) throws IOException
127 ZipArchiveOutputStream tarOut = new ZipArchiveOutputStream(new FileOutputStream(zipFile));
128 compressArchive(tarOut, findAppropriatePrefix(dest.getPath()), dest);
132 static public void main(String[] args) throws Throwable
134 // future: could use our cool code above to handle any archive type they pass.
135 if (args.length != 2) {
136 System.err.println("USAGE: PackTar {tar.gz file} {source location}");
141 PackTar.compressTarGZ(new File(args[0]), new File(args[1]));
142 } catch (Throwable t) {
143 _logger.error("failed to compress tar file " + args[0] + " from " + args[1]);
147 System.out.println("successfully compressed archive file " + args[0] + " from " + args[1]);