Category Archives: apache-commons-compress

Unpacking .tgz file in Java – Issue with Apache Compress

I'm using apache commons to unpack .tgz files. I am getting an error from the compress library. I have tried compress versions 1.9 and 1.8.1 and I am still having the same errors.

This is only happening on certain files but the kicker is when I download the file manually and validate it, there is no issues.

$ gunzip -c foo.tgz | tar t > /dev/null
$ 

However I am seeing this stack trace come from the commons library.

Severe:   java.io.IOException: Error detected parsing the header
at org.apache.commons.compress.archivers.tar.TarArchiveInputStream.getNextTarEntry(TarArchiveInputStream.java:257)    
...
Caused by: java.lang.IllegalArgumentException: Invalid byte 0 at offset 5 in '05412{NUL}11' len=8
at org.apache.commons.compress.archivers.tar.TarUtils.parseOctal(TarUtils.java:138)

The issue is coming from the line

entry = tarIn.getNextTarEntry();

Here's the code:

try {
        TarArchiveInputStream tarIn = new TarArchiveInputStream(
                new GZIPInputStream(
                        new BufferedInputStream(
                                new FileInputStream(
                                        tempDirPath + fileName))));

        TarArchiveEntry entry = tarIn.getNextTarEntry();

        while (entry != null) {
            File path = new File(tempDirPath, entry.getName());
            if (entry.isDirectory()) {
                path.mkdirs();
            } else {          
                path.createNewFile();
                byte[] read = new byte[1024];
                BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(path));
                int len;
                while ((len = tarIn.read(read)) != -1) {
                    bout.write(read, 0, len);
                }
                bout.close();
                read = null;
            }
            entry = tarIn.getNextTarEntry();
        }
        tarIn.close();
    } catch (Throwable t) {
        t.printStackTrace();
    }

apache commons compress using 7zip

i am trying to use the below code that i got from apache commons compress examples webpage to create a zip file using the sevenZ classes hoping it would be faster to compress than regular java zip. this is what my code looks like

public static void main(String[] args) {
    // TODO Auto-generated method stub
    try{
    BufferedInputStream instream = new BufferedInputStream(new FileInputStream("c:/temp/test.txt"));

    SevenZOutputFile sevenZOutput = new SevenZOutputFile(new File("c:/temp/7ztest.zip"));
    SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(new File("c:/temp/test.txt"),"blah.txt");
    sevenZOutput.putArchiveEntry(entry);
    byte[] buffer = new byte[1024];
    int len;
    while ((len = instream.read(buffer)) > 0) {sevenZOutput.write(buffer, 0, len);}

    sevenZOutput.closeArchiveEntry();
    sevenZOutput.close();
    instream.close();
    }catch(IOException ioe) {
        System.out.println(ioe.toString());

    }
}

i get this error which looks so unrelated

Exception in thread "main" java.lang.NoClassDefFoundError: org.tukaani.xz.FilterOptions at java.lang.J9VMInternals.verifyImpl(Native Method) at java.lang.J9VMInternals.verify(J9VMInternals.java:93)

i have the apache packages imported

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry; import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;

but not sure what the org.tukaani.xz.FilterOptions is, it doesnt look like it is part of the apace commons compress. Any thoughts?

Preserving directory structure with tar using ArchiveOutputStream

How can i preserve the directory structure using tar and ArchiveOutputStream? Or is there an easier way to do this?

I had this recursive method that was creating a tar of a directory. It was working fine, but it was not preserving the directory structure.

Here is what i have so far and my problem posted below.

public static void createTar(final String tarName, final List<File> pathEntries) throws IOException {
    OutputStream tarOutput = new FileOutputStream(new File(tarName));

    ArchiveOutputStream tarArchive = new TarArchiveOutputStream(tarOutput);

    recursiveAdd(tarArchive, pathEntries);

    tarArchive.finish();
    tarOutput.close();
}

public static void recursiveAdd(final ArchiveOutputStream tarArchive, final List<File> files) throws IOException {

    for (File file : files) {

        if (file != null && file.isDirectory()) {
            addFileToArchive(tarArchive, file);
            recursiveAdd(tarArchive, Arrays.asList(file.listFiles()));
        } else {
            addFileToArchive(tarArchive, file);
        }
    }
}

private static void addFileToArchive(final ArchiveOutputStream tarArchive, final File file) throws IOException {
    TarArchiveEntry tarArchiveEntry = new TarArchiveEntry(file, file.getName());
    tarArchiveEntry.setSize(file.length());
    tarArchive.putArchiveEntry(tarArchiveEntry);
    IOUtils.copy(new FileInputStream(file), tarArchive);
    tarArchive.closeArchiveEntry();
}

My problem is that it fails when it gets to a directory because

IOUtils.copy(new FileInputStream(file), tarArchive);

only works with files. How can i do this with directories as well?

Thanks