Java中的解压缩错误 [英] Unzip error in Java

查看:123
本文介绍了Java中的解压缩错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我是zip格式的新手,我使用Java的util实现来解压缩文件,但是每次尝试打开文件时,它都会引发ZipException。我检查文件是否已损坏,不是因为可以使用winRar打开它。

Hi I am quite new to zip format, and I used the Java's util implementation to unzip a file, However it throws a ZipException everytime I try to open the file. I checked to see if the file was corrupted and it is not because I can open it using winRar.

所以我继续尝试了 appache.commons.vfs 包来做同样的事情,结果也是失败。

So I moved on and tried appache.commons.vfs package to do the same thing and that too resulted in a failure.

作为最后的尝试,我尝试了7-zip-jbinding库,该库能够读取Zip存档的内容,但无法将其解压缩。

As a final try I tried the library 7-zip-jbinding and that is able to read the contents of the Zip archive but I am not able to extract it.

这是我的本机Java实现代码:

Here is my code for native java implementation:

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

我的公共菜地代码vfs

My code for 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文件提取到文件系统中,请告诉我它是如何完成的。

Is there something very obvious that I am missing? And if anyone has used 7-zip-jbinding for extracting a zip file into file system please do let me know how it is done.

编辑1:

在该文件的mac终端中执行解压缩时,向我显示以下警告

While executing a unzip in mac terminal of that file it showed me the following warning

警告:开头或结尾处多了84个字节zipfile中的内容。这会以某种方式影响Zip输入流吗?

warning : 84 extra bytes at beginning or within zipfile .. Can this somehow affect Zip input Stream ?

编辑2:

zip中的多余字节文件似乎弄乱了zip输入流..在终端上使用unzip会显示添加到zip文件中的额外字节数。我使用RandomAccessFile跳过了(n)个字节,并且Zip输入流开始正常工作..现在我要做的就是找到一种方法来删除Zip文件中的多余字节。.

The extrabytes in the zip file seemed to screw up the zip input stream .. Using unzip on the terminal shows the number of extra bytes that are added to the zip file . I Used a RandomAccessFile to skip (n) bytes and the Zip Input Stream Started working fine .. Now all i need to do is find a way to remove the extra bytes in Zip File ..

编辑后的代码粘贴在下面,以供将来使用它的任何人使用。

The edited code is pasted below for anyone who would benifit from it in the future .

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

如果有人知道跳过多余字节的方法,我将不禁大哭:)

If anyone knows a way to skip the extra bytes I am all ears :)

推荐答案

最后在我朋友的帮助下解决了这个问题

Finally solved the issue , with help of my friend ,

跳过空字节是为了继续读取直到遇到'PK'签名。因此,在程序中,输入流读取字节,直到它到达 PK为止,然后初始化Zip inputStream并传递后面的字节流。

The naive way of skipping the empty bytes is to keep reading till the 'PK' signature is encountered . So in the program an input stream reads the bytes till it hits the 'PK' once it does then it initiliases the Zip inputStream and passes the stream of bytes that follow .

下面是一种快速而肮脏的方式。将会有比这更优雅的解决方案。但是目前可行。

Below is the quick and dirty way . There will be more elegant solutions than this .. but for the moment this works .

 InputStream zipStarterStream, emptyBytecountStream;
    ZipInputStream zis;
    int BUFFER = 2048;

    /* Primary Checking to see if there is a zip file */
    File file = new File(filePath);
    if (file.exists()) {
        System.out.println("Zip found");
    } else {
        System.out.println("Zip Not found");
        return;
    }
    try {
        emptyBytecountStream = new FileInputStream(filePath);
        Charset encoding = Charset.defaultCharset();
        Reader reader = new InputStreamReader(emptyBytecountStream,
                encoding);
        int r1, r2;
        int charSkipped = 0;
        boolean foundHeader = false;

        // This is the check to skip the initial few bytes

        while ((r1 = reader.read()) != -1 && (r2 = reader.read()) != -1) {
            char ch1 = (char) r1;
            char ch2 = (char) r2;
            if (ch1 == 'P' && ch2 == 'K') {
                foundHeader = true;
                break;
            }
            charSkipped += 2;
        }
        emptyBytecountStream.close();

        zipStarterStream = new FileInputStream(filePath);
        zis = new ZipInputStream(new BufferedInputStream(zipStarterStream));

        if (foundHeader && charSkipped > 0) {
            zipStarterStream.skip(charSkipped);
        }

        String outputPath = getPublicStorageDir("")
                + "/"
                + filePath.substring(filePath.lastIndexOf("/") + 1,
                        filePath.length());

        new File(outputPath).mkdir();
        ZipEntry entry;

        while ((entry = zis.getNextEntry()) != null) {

            String currentfileName = entry.getName();
            File destFile = new File(outputPath, currentfileName);
            File destinationParent = destFile.getParentFile();

            destinationParent.mkdirs();

            if (!entry.isDirectory()) {
                int currentByte;
                byte data[] = new byte[BUFFER];

                // write the current file to disk
                FileOutputStream fos = new FileOutputStream(destFile);
                BufferedOutputStream dest = new BufferedOutputStream(fos,
                        BUFFER);

                // read and write until last byte is encountered
                while ((currentByte = zis.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, currentByte);
                }
                dest.flush();
                dest.close();
            }

            if (currentfileName.endsWith(".zip")) {
                extractZipFolder(destFile.getAbsolutePath());
            }
        }
        zis.close();
    } catch (IOException e) {
        e.printStackTrace();

    }

这篇关于Java中的解压缩错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆