Java 如何使用apachecommons解压TAR文件

Java 如何使用apachecommons解压TAR文件,java,file-io,tar,apache-commons,compression,Java,File Io,Tar,Apache Commons,Compression,我正在使用ApacheCommons1.4.1库压缩和解压缩“.tar.gz”文件 最后一位有问题--将TarArchiveInputStream转换为FileOutputStream 奇怪的是,它在这条线上断开了: FileOutputStream fout = new FileOutputStream(destPath); destPath是一个规范路径为:C:\Documents and Settings\Administrator\My Documents\JavaWorkspace

我正在使用ApacheCommons1.4.1库压缩和解压缩
“.tar.gz”
文件

最后一位有问题--将
TarArchiveInputStream
转换为
FileOutputStream

奇怪的是,它在这条线上断开了:

FileOutputStream fout = new FileOutputStream(destPath);

destPath
是一个规范路径为: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
知道会是什么吗?为什么它找不到路径呢

我附上下面的整个方法(其中大部分是从中提取的)


有两个要点,为什么要使用
文件
构造函数进行伏都教,在这里可以定义要创建的
文件的名称并给出父文件

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


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

您的程序存在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();
} 

祝你好运

谢谢你的回答。我决定重写模块,它工作得很好。我接受了你关于不要玩文件对象的建议,因此我将根据原则将你的答案标记为正确答案,很高兴它有帮助,并希望最后一切顺利。祝你好运:)我使用相同的代码来解压.tar文件,而不是.tar.gz。我从这行“newfile(dest,tarEntry.getName())”中得到的是文件内容,而不是文件名。如何将文件名放入.tar文件中?我很不好意思问这个问题,但我尝试使用了您的代码示例,并看到它在给定我使用的特定
gzip
文件的情况下工作正常。如果不调用
fout.write(…)
给定在inputStream上读取的内容,这是如何工作的?在中,他必须显式调用
write(…)
,并提供已读入内存的字节数组。因此,会发生堆空间错误,因为当字节数组声明为
byte[]btoRead=new byte[(int)tarEntry.getSize()]时,它可能太大?响应良好。但是,下面的
deskPath.createNewFile()以创建父目录

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();
}