Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to untar a TAR file using Apache Commons

I'm using the Apache Commons 1.4.1 library to compress and uncompress ".tar.gz" files.

I'm having trouble with the last bit -- converting a TarArchiveInputStream into a FileOutputStream.

Oddly enough, it's breaking on this line:

FileOutputStream fout = new FileOutputStream(destPath);

destPath is a File with a Canonical path of: C:\Documents and Settings\Administrator\My Documents\JavaWorkspace\BackupUtility\untarred\Test\subdir\testinsub.txt

Error produced:

Exception in thread "main" java.io.IOException: The system cannot find the path specified

Any idea what it could be? And why is it not able to find the path?

I'm attaching the whole method below (most of which is lifted from here).

private void untar(File dest) throws IOException {
    dest.mkdir();
    TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
    // tarIn is a TarArchiveInputStream
    while (tarEntry != null) {// create a file with the same name as the tarEntry
        File destPath = new File(dest.toString() + System.getProperty("file.separator") + tarEntry.getName());
        System.out.println("working: " + destPath.getCanonicalPath());
        if (tarEntry.isDirectory()) {
            destPath.mkdirs();
        } else {
            destPath.createNewFile();
            FileOutputStream fout = new FileOutputStream(destPath);
            tarIn.read(new byte[(int) tarEntry.getSize()]);
            fout.close();
        }
        tarEntry = tarIn.getNextTarEntry();
    }
    tarIn.close();
}
like image 330
Redandwhite Avatar asked Jul 11 '12 10:07

Redandwhite


2 Answers

Your program has the java heap space error. so I think a little change needed. here is code...

public static void uncompressTarGZ(File tarFile, File dest) throws IOException {
    dest.mkdir();
    TarArchiveInputStream tarIn = null;

    tarIn = new TarArchiveInputStream(
                new GzipCompressorInputStream(
                    new BufferedInputStream(
                        new FileInputStream(
                            tarFile
                        )
                    )
                )
            );

    TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
    // tarIn is a TarArchiveInputStream
    while (tarEntry != null) {// create a file with the same name as the tarEntry
        File destPath = new File(dest, tarEntry.getName());
        System.out.println("working: " + destPath.getCanonicalPath());
        if (tarEntry.isDirectory()) {
            destPath.mkdirs();
        } else {
            destPath.createNewFile();
            //byte [] btoRead = new byte[(int)tarEntry.getSize()];
            byte [] btoRead = new byte[1024];
            //FileInputStream fin 
            //  = new FileInputStream(destPath.getCanonicalPath());
            BufferedOutputStream bout = 
                new BufferedOutputStream(new FileOutputStream(destPath));
            int len = 0;

            while((len = tarIn.read(btoRead)) != -1)
            {
                bout.write(btoRead,0,len);
            }

            bout.close();
            btoRead = null;

        }
        tarEntry = tarIn.getNextTarEntry();
    }
    tarIn.close();
} 

good luck

like image 158
tommybee Avatar answered Sep 18 '22 15:09

tommybee


A couple of general points, why do you do voodoo with the File constructor, where there is a perfectly usable constructor where you can define the name of the File you want to create and give a parent File?

Secondly I am not too sure how empty spaces are handled in paths in windows. It might be the cause of your problems. Try using the constructor I mentioned above and see if it makes a difference: File destPath = new File(dest, tarEntry.getName()); (assuming that File dest is a proper file, and exists and is accessible by you.

Third, before you do anything with a File object you should check if it exists and if it is accessible. That will ultimately help you pinpoint the problem.

like image 45
posdef Avatar answered Sep 18 '22 15:09

posdef