Java 如何使用apachecommons解压TAR文件
我正在使用ApacheCommons1.4.1库压缩和解压缩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
“.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()如果(!destPath.getParentFile().exists()){destPath.getParentFile().mkdirs();}destPath.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();
}