我正在使用此处另一篇文章中的 apache commons compress example 从 tar 中提取文件,但它失败了:
java.io.IOException: Invalid file path.
这只发生在我传递给它的一些 vmware ova 文件(顺便说一句是 tar 文件)上,而不是所有 ova 文件;其他人工作正常。
这是代码:
public static void unTar(File tarFile, File dest) throws IOException {
dest.mkdir();
TarArchiveInputStream tarIn = null;
tarIn = new TarArchiveInputStream(
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[1024];
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();
}
看起来问题是在 tarEntry.getName() 尝试设置 destFile 的值时引入的。从使用调试器单步执行后,destPath 会拾取额外的无法显示的字符以及路径中的单词“someone”:
target/mybuildname-SNAPSHOT/extractedDirectory/<garbage characters>someone/test.ovf
对于我可以成功解压缩的 ova 文件,desPath 的值看起来很正常:
target/mybuildname-SNAPSHOT/extractedDirectory/test.ovf
“某人”文本是一个不错的线索,因为当我使用 hexdump -C 查看它时,我在两个 tar (ova) 文件头中都看到了这个文本。但是,它们不在同一个位置。
我觉得这里的解决方案与确定偏移量是存储文件名的位置并从该特定偏移量读取有关。这是我最好的猜测,但我不太擅长阅读十六进制。
需要注意的是,我的目标是读取 ova 中的 ovf xml 文件,并且我不控制 ova 的创建......所以我无法事先解决标题中的问题。ova 文件本身功能完善,我还可以使用 tar -xvf test.ova 从命令行成功解压它们。事实上,如果我从命令行重新打包 tar 文件,上面的代码就可以工作了。