Android:解压缩文件会引发数据错误或CRC错误 [英] Android: Unzipping files throws data errors or CRC errors

查看:976
本文介绍了Android:解压缩文件会引发数据错误或CRC错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个项目,该项目可以下载zip文件并在本地解压缩。我遇到的问题是,解压缩过程的工作时间约为5%。

I'm working on a project that downloads a zip file and unzips locally. The issue I'm hitting is that the unzip process works like 5% of the time.

在这一点上,这对我来说还是个谜,因为有时它可以工作,但大多数情况下引发数据或crc错误的时间。即使zip文件没有更改,它甚至会在错误之间切换。

It's a mystery to me at this point because sometimes it works, but most of the time it throws data or crc errors. It'll even switch between erros even though the zip file hasn't changed.

我尝试了由众多工具创建的zip文件,想知道格式是否不正确。但无济于事。甚至在终端中创建的拉链也不起作用。

I've tried zip files that were created by numerous tools wondering if the format was incorrect. But to no avail. Even zips created in the terminal don't work.

这是我的解压缩代码:

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文件的方式。

And here's how I typically create the zip file.

$>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)

任何人都知道为什么我会出现这些错误吗?

Anyone have any idea why I might get these errors? I'm not getting anywhere with these.

推荐答案

加载Zip文件时有两点非常重要。

There are two things very important when loading Zip files.


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

  1. Make sure you're using a request method that doesn't contain the Accept-Encoding: header. If it's in the request then the response is not a zip file, it's a gzip compressed zip file. So if you're writing that directly to disk while it's downloading then it won't actually be a zip file. You can use something like this to load the zip file:

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


  • 使用输入和输出流时,请勿使用read(buffer)或write( buffer)方法,则需要使用读/写(buffer,0,len)。否则,您正在写入或读取的内容可能最终会包含垃圾数据。前者(read(buffer))将始终读取整个缓冲区,但是实际上可能没有完整的缓冲区,例如,如果循环的最后一次迭代仅读取512个字节。因此,您可以通过以下方式解压缩文件:

  • When using input and out streams, do NOT use the read(buffer) or write(buffer) method, you need to use read/write(buffer,0,len). Otherwise what you're writing or reading may end up with garbage data in it. The former (read(buffer)) will always read the entire buffer, but there may actually not be a full buffer, for example if the last iteration of the loop only read 512 bytes. So here's how you'd unzip the file:

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


  • 这篇关于Android:解压缩文件会引发数据错误或CRC错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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