How to create a tar.gz file from a list of files

I have a List<String> files of file paths that I want to create a tar.gz from these files.  Can someone help me?  Thanks.
LVL 1
mmingfeilamAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sachiekCommented:
One option
import java.io.FileInputStream;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;

public class Taread {
    public static void main(String[] args) {
        try {
            TarArchiveInputStream tarInput = new TarArchiveInputStream(new FileInputStream(args[0]));
            TarArchiveEntry entry;
            while (null!=(entry=tarInput.getNextTarEntry())) {
                System.out.println(entry.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Open in new window

0
sachiekCommented:
Using Zipinputstream

TarInputStream tis = new TarInputStream(new FileInputStream("myfile.tar"));
try
{
    TarEntry entry;
    do
    {
        entry = tis.getNextEntry();

        //Do something with the entry
    }
    while (entry != null);
}
finally
{
    tis.close();
}

Open in new window

0
mmingfeilamAuthor Commented:
Sorry, I want to tar/compress a list of files, and then gzip it, not the other way around.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

mmingfeilamAuthor Commented:
Also I am using jdk 1.7.
0
sachiekCommented:
Here you go..use this bit of code.. You will be able to create tar.gz

protected void makeCompress(String srcFile) throws IOException {  
    File outFile = new File(srcFile + ".tar");  
    List<File> list = new ArrayList<>(1);  
    File file = new File(srcFile);  
    list.add(file);  
    compressFiles(list, outFile);         
}  
   
private void compressFiles(List<File> list, File outFile) throws IOException {  
    try (TarArchiveOutputStream taos = new TarArchiveOutputStream(
            new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(outFile))))) {
 
        taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR);  
        taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);  
           
        for (File f : list) {
            System.out.println("send to cmpress: " + f.getName());  
            addFileToCompression(taos, f, ".");  
        }  
    } // all streams are automatically closed here, whether an exception occurs or not
}  
   
private void addFileToCompression(TarArchiveOutputStream taos, File f, String dir) throws IOException {  
    System.out.println(f.getName() + " dir : " + dir);  
    TarArchiveEntry tae = new TarArchiveEntry(f, dir + "/");          
    taos.putArchiveEntry(tae);  
    if (f.isDirectory()) {  
        /*TarArchiveEntry tae = new TarArchiveEntry(f, dir + "/");       
        taos.putArchiveEntry(tae);*/ 
        System.out.println("is a directory");  
        taos.closeArchiveEntry();  
        for (File childFile : f.listFiles()) {  
            System.out.println("child: " + childFile.getName());  
            addFileToCompression(taos, childFile, dir + "/" + f.getName() + "/" + childFile.getName());  
        }  
    } else {  
        System.out.println("is a file " + f.getName());  
        try (FileInputStream fis = new FileInputStream(f)) {
            IOUtils.copy(fis, taos);  
        }  
        System.out.println("file added");  
        taos.flush();  
        taos.closeArchiveEntry();  
    }
}

Open in new window

0
sachiekCommented:
Line no.2..update with this below code.

File outFile = new File(srcFile + ".tar.gz");

Open in new window

0
sachiekCommented:
the way the TarArchiveEntry is created - without the "/" added to the entry name. With the "/" I get a .tar.gz file with only folders, not files.
0
mmingfeilamAuthor Commented:
makeCompress() is not being used at all.  I am trying this:

 public static void main( String[] args ) throws IOException, InterruptedException
    {
    		List<File> fileList = new ArrayList<File>();
    		fileList.add(new File("/Users/212353126/Documents/Renewables/pub/appdata/data/temp/ba_11600002_1446535324358.csv"));
    		fileList.add(new File("/Users/212353126/Documents/Renewables/pub/appdata/data/temp/mk_11600025_1446535324358.csv"));

    		TarGZDemo demo = new TarGZDemo();
    		demo.compressFiles(fileList, new File("/Users/212353126/Documents/Renewables/pub/appdata/data/temp/test.tar.gz"));
    }

Open in new window


I do get a .tar.gz file, but when I do tar -zxvf test.tar.gz I get an empty error.
0
sachiekCommented:
Try to use this code.

/**
 * Compress (tar.gz) the input file (or directory) to the output file
 * <p/>
 *
 * In the case of a directory all files within the directory (and all nested
 * directories) will be added to the archive
 *
 * @param file The file(s if a directory) to compress
 * @param output The resulting output file (should end in .tar.gz)
 * @throws IOException
 */
public static void compressFile(File file, File output)
	throws IOException
{
	ArrayList<File> list = new ArrayList<File>(1);
	list.add(file);
	compressFiles(list, output);
}

/**
 * Compress (tar.gz) the input files to the output file
 *
 * @param files The files to compress
 * @param output The resulting output file (should end in .tar.gz)
 * @throws IOException
 */
public static void compressFiles(Collection<File> files, File output)
	throws IOException
{
	LOG.debug("Compressing "+files.size() + " to "+output.getAbsoluteFile());
               // Create the output stream for the output file
	FileOutputStream fos = new FileOutputStream(output);
               // Wrap the output file stream in streams that will tar and gzip everything
	TarArchiveOutputStream taos = new TarArchiveOutputStream(
		new GZIPOutputStream(new BufferedOutputStream(fos)));
               // TAR has an 8 gig file limit by default, this gets around that
	taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR); // to get past the 8 gig limit
               // TAR originally didn't support long file names, so enable the support for it
	taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

               // Get to putting all the files in the compressed output file
	for (File f : files) {
		addFilesToCompression(taos, f, ".");
	}

               // Close everything up
	taos.close();
	fos.close();
}

/**
 * Does the work of compression and going recursive for nested directories
 * <p/>
 *
 * Borrowed heavily from http://www.thoughtspark.org/node/53
 *
 * @param taos The archive
 * @param file The file to add to the archive
        * @param dir The directory that should serve as the parent directory in the archivew
 * @throws IOException
 */
private static void addFilesToCompression(TarArchiveOutputStream taos, File file, String dir)
	throws IOException
{
               // Create an entry for the file
	taos.putArchiveEntry(new TarArchiveEntry(file, dir+FILE_SEPARATOR+file.getName()));
	if (file.isFile()) {
                       // Add the file to the archive
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
		IOUtils.copy(bis, taos);
		taos.closeArchiveEntry();
		bis.close();
	}
	else if (file.isDirectory()) {
                       // close the archive entry
		taos.closeArchiveEntry();
                       // go through all the files in the directory and using recursion, add them to the archive
		for (File childFile : file.listFiles()) {
			//addFilesToCompression(taos, childFile, file.getName());
                       addFilesToCompression(taos, childFile, dir + File.seperator + file.getName());
		}
	}
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CEHJCommented:
This, if the context allows you to do it, is tons easier of course:

        List<String> files = ...
	List<String> args = new ArrayList<>();
	args.add("tar");
	args.add("cvfz");
	args.add("test.tar.gz");
	args.addAll(files);
	ProcessBuilder pb = new ProcessBuilder(args);
	pb.redirectError(new File("err.log"));
	pb.redirectOutput(new File("out.log"));
	pb.start();

Open in new window

You can get rid of the stdout log but i wouldn't get rid of the stderr one
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.