将 DynamoDB 表中的现有字符串压缩为字符串:ZipException:不是 GZIP 格式

问题描述 投票:0回答:1

我们想要压缩 DynamoDB 表中的一个大字符串,它是一个 JSON 对象。

我想简单地用压缩字符串替换它。我查看了 DynamoDB 文档,它使用 ByteBuffer 直接存储,如here所述。

但是由于我不想保存 ByteArray,而是存储原始字符串的压缩字符串版本,所以我对其进行了修改。

这是我所做的:

public class GZIPStringCompression {
    public static String compress(String data) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(data.length());
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
        gzipOutputStream.write(data.getBytes());
        gzipOutputStream.close();
        return byteArrayOutputStream.toString();
    }

    public static String decompress(String compressed) throws IOException {
        ByteArrayInputStream bis = new ByteArrayInputStream(compressed.getBytes());
        GZIPInputStream gis = new GZIPInputStream(bis);
        BufferedReader br = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        String line;
        while((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        gis.close();
        bis.close();
        return sb.toString();
    }
}

这给出了例外:

Exception in thread "main" java.util.zip.ZipException: Not in GZIP format
    at java.base/java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:165)
    at java.base/java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
    at java.base/java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
    at GZIPStringCompression.decompress(MyClass.java:41)
    at MyClass.main(MyClass.java:16)

我不确定我想要的是否可能,所以,想在这里确认一下。


将此更改为:

class GZIPStringCompression {
    public static String compress(String data) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(data.length());
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
        gzipOutputStream.write(data.getBytes());
        gzipOutputStream.close();
        return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }

    public static String decompress(String compressed) throws IOException {

        ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(compressed));
        GZIPInputStream gis = new GZIPInputStream(bis);
        BufferedReader br = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        String line;
        while((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        gis.close();
        bis.close();
        return sb.toString();
    }
}

这不知怎的奏效了。这是一个可靠的解决方案吗?

arrays amazon-dynamodb gzip bytebuffer
1个回答
1
投票

u200e您的第一个解决方案不起作用,因为您想要获取一个字节数组(8 位字节数组)并将其分配给一个 String 属性(基本上是一个 unicode 字符数组)。这没有意义,可能会导致对您的字节进行各种不需要的操作,从而使您在读回它们时无法使用它们。

将字节数组转换为 base-64 编码(基本上是 ASCII 的子集)的方法是有效的,因为 ASCII 字符确实可以在字符串中表示,无需任何操作,并且可以像写入一样读回。

既然您提到这是针对 DynamoDB 的,我应该添加 DynamoDB 除了“字符串”类型之外还有“二进制”类型,您可以使用它。在 Java 中,您可以将字节数组直接分配给这种类型的属性 - 并且不需要尝试将其“转换”为字符串。

© www.soinside.com 2019 - 2024. All rights reserved.