嗨,我对 zip 格式很陌生,我使用 Java 的 util 实现来解压缩文件,但是每次我尝试打开文件时都会引发 ZipException。我检查了文件是否已损坏,这不是因为我可以使用 winRar 打开它。
所以我继续前进并尝试使用appache.commons.vfs
package 来做同样的事情,这也导致了失败。
作为最后一次尝试,我尝试了库 7-zip-jbinding,它能够读取 Zip 存档的内容,但我无法提取它。
这是我的本机 java 实现代码:
BufferedOutputStream dest = null;
FileInputStream fis = new FileInputStream(archive);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
File destFile;
destinationDir.mkdir();
while ((entry = zis.getNextEntry()) != null) {
String currentfileName = entry.getName();
destFile = new File(destinationDir, currentfileName);
File destinationParent = destFile.getParentFile();
destinationParent.mkdirs();
if (!entry.isDirectory()) {
int currentByte;
byte data[] = new byte[BUFFER_SIZE];
FileOutputStream fos = new FileOutputStream(destFile);
dest = new BufferedOutputStream(fos, BUFFER_SIZE);
while ((currentByte = zis.read(data, 0, BUFFER_SIZE)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
}
}
fis.close();
zis.close();
我的 appache commons vfs 代码
public void unpack(final File outputDir,URI packLocation) throws IOException
{
this.packLocation = packLocation;
this.fileSystemManager = VFS.getManager();
outputDir.mkdirs();
final FileObject packFileObject = fileSystemManager.resolveFile(packLocation.toString());
try
{
final FileObject zipFileSystem = fileSystemManager.createFileSystem(packFileObject);
try
{
fileSystemManager.toFileObject(outputDir).copyFrom(zipFileSystem, new AllFileSelector());
}
finally
{
zipFileSystem.close();
}
}
finally
{
packFileObject.close();
}
}
有什么很明显的我想念的吗?如果有人使用 7-zip-jbinding 将 zip 文件提取到文件系统中,请告诉我它是如何完成的。
编辑1:
在该文件的mac终端中执行解压缩时,它向我显示了以下警告
警告:在 zipfile 的开头或内部有 84 个额外字节。这会以某种方式影响 Zip 输入流吗?
编辑2:
zip 文件中的额外字节似乎搞砸了 zip 输入流。在终端上使用 unzip 会显示添加到 zip 文件中的额外字节数。我使用 RandomAccessFile 跳过(n)个字节并且 Zip 输入流开始正常工作.. 现在我需要做的就是找到一种方法来删除 Zip 文件中的额外字节..
编辑后的代码粘贴在下面,以供将来从中受益的任何人使用。
final int BUFFER_SIZE = 1024;
RandomAccessFile randomAccessFile = new RandomAccessFile(archive, "r");
randomAccessFile.skipBytes(84); // The extra bytes
FileChannel channel = randomAccessFile.getChannel();
BufferedOutputStream dest = null;
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(Channels.newInputStream(channel)));
ZipEntry entry;
File destFile;
destinationDir.mkdir();
while ((entry = zis.getNextEntry()) != null) {
String currentfileName = entry.getName();
destFile = new File(destinationDir, currentfileName);
File destinationParent = destFile.getParentFile();
destinationParent.mkdirs();
if (!entry.isDirectory()) {
int currentByte;
byte data[] = new byte[BUFFER_SIZE];
FileOutputStream fos = new FileOutputStream(destFile);
dest = new BufferedOutputStream(fos, BUFFER_SIZE);
while ((currentByte = zis.read(data, 0, BUFFER_SIZE)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
}
}
zis.close();
如果有人知道跳过额外字节的方法,我会全神贯注:)