如何使用Apache Commons解压缩TAR文件

时间:2012-07-11 10:56:21

标签: java file-io tar apache-commons compression

我正在使用Apache Commons 1.4.1库来压缩和解压缩".tar.gz"个文件。

我在最后一位遇到问题 - 将TarArchiveInputStream转换为FileOutputStream

奇怪的是,它在这条线上打破了:

FileOutputStream fout = new FileOutputStream(destPath);

destPath是一个文件,其Canonical路径为:C:\ Documents and Settings \ Administrator \ My Documents \ JavaWorkspace \ BackupUtility \ untarred \ Test \ subdir \ testinsub.txt

产生错误:

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

知道它可能是什么?为什么它找不到路径?

我附上了下面的整个方法(其中大部分是从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();
}

2 个答案:

答案 0 :(得分:16)

您的程序有java堆空间错误。 所以我认为需要做一点改变。 这是代码......

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();
} 
祝你好运

答案 1 :(得分:5)

有几个一般要点,为什么你使用File构造函数进行voodoo,其中有一个perfectly usable constructor,您可以在其中定义要创建的File的名称给一个父文件?

其次,我不太确定在Windows中的路径中如何处理空白空间。这可能是你问题的原因。尝试使用我上面提到的构造函数,看看它是否有所不同:File destPath = new File(dest, tarEntry.getName());(假设File dest是一个正确的文件,并且存在且可供您访问。

第三,在对File对象执行任何操作之前,应检查它是否存在以及是否可访问。这最终将帮助您查明问题。