我正在开发一个下载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)
任何人都知道为什么我会收到这些错误?我没有随处可见。
答案 0 :(得分:6)
加载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)。否则,您正在编写或阅读的内容最终可能会包含垃圾数据。前者(读取(缓冲区))将始终读取整个缓冲区,但实际上可能没有完整的缓冲区,例如,如果循环的最后一次迭代只读取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();