Unzip7z.groovy

import static java.lang.System.err as error

import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.io.RandomAccessFile
import java.util.Arrays

import net.sf.sevenzipjbinding.ExtractOperationResult
import net.sf.sevenzipjbinding.ISequentialOutStream
import net.sf.sevenzipjbinding.SevenZip
import net.sf.sevenzipjbinding.SevenZipException
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream
import net.sf.sevenzipjbinding.simple.ISimpleInArchive
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem

def fileToUnzip = "#VARIABLE"

def basePath =  new File(fileToUnzip).getParent()

println basePath

try{
    RandomAccessFile randomAccessFile = new RandomAccessFile(fileToUnzip, "r")
    //  ISevenZipInArchive
    net.sf.sevenzipjbinding.IInArchive inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile))

    ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface()

    println "${'Hash'.center(10)}|${'Size'.center(12)}|${'Filename'.center(10)}"
    println "${'-'.multiply(10)}+${'-'.multiply(12)}+${'-'.multiply(10)}"

    simpleInArchive.getArchiveItems().each
            { item ->
                final int[] hash = new int[1]
                if (!item.isFolder())
                {
                    final long[] sizeArray = new long[1]
                    ExtractOperationResult result = item.extractSlow(
                            new ISequentialOutStream()
                            {
                                public int write(byte[] data) throws SevenZipException
                                {
                                    def name = item.getPath().contains("/") ? item.getPath().substring(item.getPath().indexOf("/")) :  item.getPath()
                                    File file = new File(basePath, name )
                                    file.getParentFile()?.mkdirs()
                                    FileOutputStream fos = new FileOutputStream(file, true)
                                    fos.write(data)
                                    fos.close()
                                    hash[0] ^= Arrays.hashCode(data) // Consume data
                                    sizeArray[0] += data.length
                                    return data.length // Return amount of consumed data
                                }
                            })
                    if (result == ExtractOperationResult.OK)
                    {
                        println(String.format("%9X | %10s | %s",
                                hash[0], sizeArray[0], item.getPath()))
                    }
                    else
                    {
                        throw new RuntimeException("Error extracting item: " + result)
                    }
                }
            }
}
finally
{
    if (inArchive != null)
    {
        try
        {
            inArchive.close()
        }
        catch (SevenZipException e)
        {
            throw new RuntimeException("Error closing archive", e)
        }
    }
    if (randomAccessFile != null)
    {
        try
        {
            randomAccessFile.close()
        }
        catch (IOException e)
        {
            throw new RuntimeException("Error closing file", e)
        }
    }
}