首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java ZipInputStream提取错误

Java ZipInputStream提取错误
EN

Stack Overflow用户
提问于 2017-04-20 01:28:00
回答 2查看 1K关注 0票数 1

下面是一些代码,它从只包含一个文件的zip文件中提取一个文件。但是,提取的文件与通过WinZip或其他zip实用程序提取的文件不匹配。如果文件包含奇数字节(因为我的缓冲区大小为2,读取失败时我只是中止),那么它可能会被一个字节关闭。但是,当分析(使用WinMerge或Diff)使用下面的代码提取的文件与通过Winzip提取的文件时,有几个区域缺少字节。有人知道为什么或者我怎么能解决这个问题吗?

代码语言:javascript
运行
复制
package zipinputtest;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipInputStream;

public class test2 {
    public static void main(String[] args) {
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream("C:\\temp\\sample3.zip"));
            File outputfile = new File("C:\\temp\\sample3.bin");
            OutputStream os = new BufferedOutputStream(new FileOutputStream(outputfile));
            byte[] buffer2 = new byte[2];
            zis.getNextEntry();
            while(true) {
                if(zis.read(buffer2) != -1) {
                    os.write(buffer2);
                }
                else break;
            }
            os.flush();
            os.close();
            zis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我能够使用此映像生成错误(将其保存为sample3.zip并在其上运行代码),但任何足够大小的二进制文件都应显示差异。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-20 02:01:25

代码语言:javascript
运行
复制
while (true) {
    if(zis.read(buffer2) != -1) {
        os.write(buffer2);
    }
    else break;
}

常见的问题。你忽略了伯爵。应:

代码语言:javascript
运行
复制
int count;
while ((count = zis.read(buffer2)) != -1)
{
    os.write(buffer2, 0, count);
}

注:

  1. 缓冲区大小为2是荒谬的。使用8192或更多。
  2. flush()close()之前是多余的。
票数 2
EN

Stack Overflow用户

发布于 2017-04-20 01:39:32

您可以使用一种更逐字的方法来检查是否所有字节都是读和写的,例如

代码语言:javascript
运行
复制
  public int extract(ZipInputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE];
    int total = 0;
    int read;
    while ((read = in.read(buffer)) != -1) {
      total += read;
      out.write(buffer, 0, read);
    }
    return total;
  }

如果read参数未在write()中使用,则该方法假设将写出buffer的全部内容,如果buffer未完全填充,则可能不正确。

OutputStream可以在extract()方法内部或外部被刷新和关闭。调用close()就足够了,因为它也调用了flush()

无论如何,Java的“标准”I/O代码(就像java.util.zip包一样)已经过广泛的测试和使用,所以它不太可能有一个非常基本的错误,以至于很容易丢失字节。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43508690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档