Android:解压缩文件会引发数据错误或CRC错误

Android:解压缩文件会引发数据错误或CRC错误,android,exception,zip,Android,Exception,Zip,我正在做一个项目,下载一个zip文件并在本地解压。我遇到的问题是解压过程在5%的时间内都能正常工作 在这一点上,这对我来说是个谜,因为有时它可以工作,但大多数时候它抛出数据或crc错误。即使zip文件没有更改,它也会在错误之间切换 我试过许多工具创建的zip文件,想知道格式是否不正确。但是没有用。即使在终端中创建的拉链也不起作用 以下是我的解压缩代码: try { String _location = model.getLocalPath(); FileInputStream f

我正在做一个项目,下载一个zip文件并在本地解压。我遇到的问题是解压过程在5%的时间内都能正常工作

在这一点上,这对我来说是个谜,因为有时它可以工作,但大多数时候它抛出数据或crc错误。即使zip文件没有更改,它也会在错误之间切换

我试过许多工具创建的zip文件,想知道格式是否不正确。但是没有用。即使在终端中创建的拉链也不起作用

以下是我的解压缩代码:

try {
    String _location = model.getLocalPath();
    FileInputStream fin = new FileInputStream(localFile);
    ZipInputStream zin = new ZipInputStream(fin);
    ZipEntry ze = null; 
    byte[] buffer = new byte[1024];
    while((ze = zin.getNextEntry()) != null) {
        if(_cancel) break; 

        System.out.println("unzipping " + ze.getName());

        if(ze.isDirectory()) {
            File f = new File(_location + ze.getName());
            f.mkdirs();
        } else { 

            FileOutputStream fout = new FileOutputStream(_location + ze.getName());
            for(int c = zin.read(buffer); c > 0; c = zin.read(buffer)) {
                fout.write(buffer,0,c);
            }
            zin.closeEntry();
            fout.close();
        }
    }
    zin.close();

    if(_cancel) {
        handler.post(dispatchCancel);
        return;
    }

} catch(Exception e) {
    System.out.println("UNZIP ERROR!");
    System.out.println(e.getMessage());
    System.out.println(e.toString());
    e.printStackTrace();
}
下面是我通常创建zip文件的方式

$>zip -r myzip.zip myzip/
以下是两个错误输出:

java.util.zip.ZipException: CRC mismatch
    at java.util.zip.ZipInputStream.readAndVerifyDataDescriptor(ZipInputStream.java:209)
    at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:173)
    at com.XX.XX.XXIssueDownloader$7.run(XXIssueDownloader.java:222)
    at java.lang.Thread.run(Thread.java:1020)

java.util.zip.ZipException: data error
    at java.util.zip.ZipInputStream.read(ZipInputStream.java:336)
    at java.io.FilterInputStream.read(FilterInputStream.java:133)
    at com.XX.XX.XXIssueDownloader$7.run(XXIssueDownloader.java:219)
    at java.lang.Thread.run(Thread.java:1020)

有人知道我为什么会犯这些错误吗?在加载Zip文件时,有两件事非常重要

  • 确保您使用的请求方法不包含Accept Encoding:标头。如果它在请求中,那么响应不是zip文件,而是gzip压缩的zip文件。所以,如果您在下载时直接将其写入磁盘,那么它实际上不会是zip文件。您可以使用类似以下内容加载zip文件:

    URL url = new URL(remoteFilePath);
    URLConnection connection = url.openConnection();
    InputStream in = new BufferedInputStream(connection.getInputStream());
    FileOutputStream f = new FileOutputStream(localFile);
    
    //setup buffers and loop through data
    byte[] buffer = new byte[1024];
    long total = 0;
    long fileLength = connection.getContentLength();
    int len1 = 0;
    while((len1 = in.read(buffer)) != -1) {
            if(_cancel) break;
            total += len1;
            _Progress = (int) (total * 100 / fileLength);
            f.write(buffer,0,len1);
            handler.post(updateProgress);
    }
    f.close();
    in.close();
    
  • 使用输入和输出流时,不要使用读(缓冲区)或写(缓冲区)方法,您需要使用读/写(缓冲区,0,len)。否则,您正在编写或读取的内容可能最终会包含垃圾数据。前者(read(buffer))将始终读取整个缓冲区,但实际上可能没有完整的缓冲区,例如,如果循环的最后一次迭代仅读取512字节。下面是解压文件的方法:

    String _location = model.getLocalPath();
    FileInputStream fin = new FileInputStream(localFile);
    ZipInputStream zin = new ZipInputStream(fin);
    ZipEntry ze = null; 
    
    while((ze = zin.getNextEntry()) != null) {
            if(_cancel) break;  
            System.out.println("unzipping " + ze.getName());
            System.out.println("to: " + _location + ze.getName());
            if(ze.isDirectory()) {
                    File f = new File(_location + ze.getName());
                    f.mkdirs();
            } else { 
                    byte[] buffer2 = new byte[1024];
                    FileOutputStream fout = new FileOutputStream(_location + ze.getName());
                    for(int c = zin.read(buffer2); c > 0; c = zin.read(buffer2)) {
                            fout.write(buffer2,0,c);
                    }
                    zin.closeEntry();
                    fout.close();
            }
    }
    zin.close();
    

  • 太好了,我得到了
    CRC错误
    ,只是因为下载的zip文件坏了。我使用
    f.write(缓冲区,0,len1)
    而不是我的代码中的
    f.write(buffer)
    ,然后这个问题就解决了。谢谢。当我试图在我的Android设备上解压apk文件时,我收到了crcError。我猜你们谈论的代码是针对个人电脑上的Eclipse(或类似产品)的。如果我想从我的Android设备(三星Galaxy Note 2和Android 4.1.2)上解压这些东西,如何避免这个错误?谢谢!:)@wodong-I已经在使用f.write(缓冲区,0,len1);在我的回答代码中example@VanyaBurduk-确保彻底检查我的应答码。确保没有读写错误长度的问题。谢谢。事实上,我改变了
    f.write(缓冲区)写入
    f.write(缓冲区,0,len1)让一切变得不同。允许停止CRC检查错误。