嗨,我是zip格式的新手,我使用Java的util实现来解压缩文件,但是每当我尝试打开文件时它都会抛出一个ZipException . 我检查文件是否已损坏,但不是因为我可以使用winRar打开它 .
所以我继续尝试 appache.commons.vfs
包来做同样的事情,这也导致了失败 .
作为最后的尝试,我尝试了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代码为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文件中的extrabytes似乎搞砸了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();
如果有人知道一种方法来跳过额外的字节我都是耳朵:)
2 回答
终于在朋友的帮助下解决了这个问题,
跳过空字节的天真方式是继续读取,直到遇到'PK'签名 . 因此在程序中,输入流读取字节,直到它达到'PK'为止,然后它启动Zip inputStream并传递后面的字节流 .
以下是快速而肮脏的方式 . 将有更优雅的解决方案..但目前这是有效的 .
什么是确切的异常消息?
请注意,ZIP文件可能存在格式差异 . 例如:您使用加密吗?这对于内置的java例程来说是个问题 .
并且:您是否尝试使用其他ZIP工具重新打包?