java - GZIPInputStream .read() 限制

标签 java base64 gzip compression

我正在尝试在 Java 中使用 GZIPInputStream 来解压缩来自 .NET 应用程序的图像数据(以 GZIP 格式压缩)。图像数据作为 base64 字符串传输,因为它作为 XML 文本同步。我假设流会读入传递给 .read() 参数的缓冲区,直到缓冲区饱和。它没有像我预期的那样工作,即 .read() 只能读取每个读取操作 800 左右的字节。对于小图像来说这不是问题,但对于大图像(例如 800 KB),解压需要很长时间。我编写了一个小测试示例来展示这一点:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZIPtest {

public static void main(String[] args) throws IOException {
    String b64img = "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";
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    GZIPOutputStream gzos = new GZIPOutputStream(bos);
    gzos.write(b64img.getBytes());
    gzos.close();

    byte[] compressed = bos.toByteArray();
    ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
    GZIPInputStream gzis = new GZIPInputStream(bis);
    int bufSize = 8192;
    byte[] decompressed = new byte[bufSize];
    int read = gzis.read(decompressed);
    String s = new String(decompressed, 0, read);
    while (read != -1) {
        decompressed = new byte[bufSize];
        read = gzis.read(decompressed);
        String tmp = "";
        if (read != -1) {
            tmp = new String(decompressed, 0, read);
            s += tmp;
        }
    }
    gzis.close();
    if (b64img.equals(s))
        System.out.print("EQUAL");
    System.exit(0);
}

}

b64imgthis image 的 Base64 表示形式。这是一个简单的 6 KB 镜像,因此运行该程序不会花费很长时间。如果您逐步完成读取过程,您将发现它不会使解压缩字节缓冲区饱和。

我使用 print 语句来查看压缩/解压缩的字符串是否相等,作为我自己的测试来查看 GZIP 是否正常工作。

最佳答案

srkavin是正确的。您可以使用 GZIPInputStream 的构造函数设置缓冲区大小。

关于java - GZIPInputStream .read() 限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20807192/

相关文章:

python - 在 Base64 编码后恢复表示图像的 numpy 数组

Python:二进制到 Base64

amazon-web-services - 以 S3 网站为源的 CloudFront 不提供压缩文件

java - 如何在Java中获取gzip内文件的时间戳

java - 使用 GWT 显示 div 层

java - Jacoco 代理 - Spring Boot 应用程序的空执行文件

java - Java 中的 Base64 Ascii 编码

python - 如何将 gz 文件附加到 python 中的 json 对象?

java - 如何从 JButton 的操作中获取 JTextField 中的字符串?

java - Java中如何从字符串格式中获取年、月、日