gpt4 book ai didi

java - 解压缩到 ByteArrayOutputStream - 为什么我会收到 EOFException?

转载 作者:行者123 更新时间:2023-12-02 09:12:09 25 4
gpt4 key购买 nike

我一直在尝试创建一个 Java 程序,该程序将从在线 API 读取 zip 文件,将它们解压缩到内存中(而不是文件系统中),然后将它们加载到数据库中。 由于解压缩的文件需要按特定顺序加载到数据库中,因此我必须在加载任何文件之前解压缩所有文件。

我基本上用了another question StackOverflow 上作为如何做到这一点的模型。使用 util.zip 中的 ZipInputStream 我能够使用较小的 ZIP(压缩 0.7MB ~ 解压 4MB)来完成此操作,但是当我遇到更大的文件(压缩 25MB,解压后135MB),最大的两个文件没有读入内存。我什至无法检索这些较大文件(8MB 和 120MB,后者构成 zip 文件中的绝大多数数据)的 ZipEntry。没有抛出任何异常,我的程序继续执行,直到它尝试访问无法写入的解压文件,并抛出 NullPointerException。

我正在使用 Jsoup 从网上获取 zip 文件。

有谁有这方面的经验并可以指导我为什么无法检索 zip 文件的完整内容吗?

下面是我正在使用的代码。我正在 HashMap 中将解压缩的文件作为 InputStream 收集,当不再有 ZipEntry 时,程序应该停止寻找 ZipEntry当没有更多的时候。

    private Map<String, InputStream> unzip(ZipInputStream verZip) throws IOException {

Map<String, InputStream> result = new HashMap<>();

while (true) {
ZipEntry entry;
byte[] b = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int l;

entry = verZip.getNextEntry();//Might throw IOException

if (entry == null) {
break;
}

try {
while ((l = verZip.read(b)) > 0) {
out.write(b, 0, l);
}
out.flush();
}catch(EOFException e){
e.printStackTrace();
}
catch (IOException i) {
System.out.println("there was an ioexception");
i.printStackTrace();
fail();
}
result.put(entry.getName(), new ByteArrayInputStream(out.toByteArray()));
}
return result;
}

如果我的程序利用文件系统来解压缩文件,我的情况可能会更好吗?

最佳答案

事实证明,Jsoup 是问题的根源。使用 Jsoup 连接获取二进制数据时,从连接读取的字节数是有限制的。默认情况下,此限制为 1048576,即 1 兆字节。因此,当我将 Jsoup 中的二进制数据输入 ZipInputStream 时,生成的数据在 1 MB 后被截断。此限制 maxBodySizeBytes 可以在 org.jsoup.helper.HttpConnection.Request 中找到。

        Connection c = Jsoup.connect("example.com/download").ignoreContentType(true);
//^^returns a Connection that will only retrieve 1MB of data
InputStream oneMb = c.execute().bodyStream();
ZipInputStream oneMbZip = new ZipInputStream(oneMb);

尝试解压缩截断的 oneMbZip 导致我得到 EOFException

使用下面的代码,我能够将 Connection 的字节限制更改为 1 GB (1073741824),然后能够检索 zip 文件,而不会遇到 EOFException.

        Connection c = Jsoup.connect("example.com/download").ignoreContentType(true);
//^^returns a Connection that will only retrieve 1MB of data
Connection.Request theRequest = c.request();
theRequest.maxBodySize(1073741824);
c.request(theRequest);//Now this connection will retrieve as much as 1GB of data
InputStream oneGb = c.execute().bodyStream();
ZipInputStream oneGbZip = new ZipInputStream(oneGb);

请注意,maxBodySizeBytes 是一个 int,其上限为 2,147,483,647,即略低于 2GB。

关于java - 解压缩到 ByteArrayOutputStream - 为什么我会收到 EOFException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59313819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com