将 DynamoDB table 中的现有字符串压缩为字符串:ZipException:不是 GZIP 格式
Compress an existing string in DynamoDB table to a string : ZipException: Not in GZIP format
我们想在 DynamoDB table 中压缩一个大字符串,它是一个 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();
}
}
这在某种程度上奏效了。这是一个可靠的解决方案吗?
你的第一个解决方案没有用,因为你想获取一个字节数组(8 位字节数组)并将其分配给一个字符串属性(基本上是一个 unicode 字符数组)。这没有意义可能会导致对您的字节进行各种不需要的操作,从而使它们在您读回时无法使用。
您将字节数组转换为 base-64 编码的方法(基本上是 ASCII 的一个子集)有效,因为 ASCII 字符确实可以在不进行任何操作的情况下表示为字符串,并且可以像写入时一样读回.
既然你提到这是针对 DynamoDB 的,我应该补充一下 DynamoDB 除了“字符串”类型之外还有“二进制”类型,你可以直接使用它。在 Java 中,您可以将字节数组直接分配给此类型的属性 - 而无需尝试将其“转换”为字符串。
我们想在 DynamoDB table 中压缩一个大字符串,它是一个 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();
}
}
这在某种程度上奏效了。这是一个可靠的解决方案吗?
你的第一个解决方案没有用,因为你想获取一个字节数组(8 位字节数组)并将其分配给一个字符串属性(基本上是一个 unicode 字符数组)。这没有意义可能会导致对您的字节进行各种不需要的操作,从而使它们在您读回时无法使用。
您将字节数组转换为 base-64 编码的方法(基本上是 ASCII 的一个子集)有效,因为 ASCII 字符确实可以在不进行任何操作的情况下表示为字符串,并且可以像写入时一样读回.
既然你提到这是针对 DynamoDB 的,我应该补充一下 DynamoDB 除了“字符串”类型之外还有“二进制”类型,你可以直接使用它。在 Java 中,您可以将字节数组直接分配给此类型的属性 - 而无需尝试将其“转换”为字符串。