java - 在 Java 中压缩和解压缩字符串
问题描述
我正在尝试从生产者和消费者环境中压缩和解压缩一个字符串(它只接受字符串作为参数)。
因此,在压缩字符串后,我将压缩字节数组转换为字符串,然后将其传递给生产者。然后在消费者部分,我将字符串取回,转换为字节数组,然后从字节中解压缩字符串。
如果我使用 byte[] 而不是转换成字符串,那么它工作正常。但我需要的是转换成字符串,反之亦然。
这是我的代码:
public class Compression {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
String strToCompress = "Helloo!! ";
byte[] compressedBytes = compress(strToCompress);
String compressedStr = new String(compressedBytes, StandardCharsets.UTF_8);
byte[] bytesToDecompress = compressedStr.getBytes(StandardCharsets.UTF_8);
String decompressedStr = decompress(bytesToDecompress);
System.out.println("Compressed Bytes : "+Arrays.toString(compressedBytes));
System.out.println("Decompressed String : "+decompressedStr);
}
public static byte[] compress(final String str) throws IOException {
if ((str == null) || (str.length() == 0)) {
return null;
}
ByteArrayOutputStream obj = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj);
gzip.write(str.getBytes("UTF-8"));
gzip.flush();
gzip.close();
return obj.toByteArray();
}
public static String decompress(final byte[] compressed) throws IOException {
final StringBuilder outStr = new StringBuilder();
if ((compressed == null) || (compressed.length == 0)) {
return "";
}
if (isCompressed(compressed)) { //It is not going into this if part
final GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(compressed));
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
outStr.append(line);
}
} else {
outStr.append(compressed);
}
return outStr.toString();
}
public static boolean isCompressed(final byte[] compressed) {
return (compressed[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (compressed[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8));
}
}
解决方案
您不能假设压缩字符串可以被视为 UTF-8,因为许多可能的字节组合都不是有效的 UTF-8。我建议尝试 ISO-8859-1,它保留所有 8 位值不翻译。
另请注意,虽然大段文本应该变小,但小字符串可以变大。
注意:此循环将删除任何换行符
String line;
while ((line = bufferedReader.readLine()) != null) {
outStr.append(line);
}
我建议改为使用char[]
不会丢失任何字符的复制。
char[] chars = new char[512];
for(int len; (len = reader.read(chars)) > 0;)
outStr.append(chars, 0, len);
推荐阅读
- sql - 在 SQL Server 中将 Varbinary 转换为 PDF
- dkim - 我可以只为一台特定的服务器配置 DKIM 吗?
- extjs - EXTJS:Ext.widget 和 Ext.create 有什么区别?
- deployment - 无法使用 apache2 mod_wsgi 设置 odoo
- java - 部署 Springboot Web 服务 Heroku。配置 Dyno 形成时出现错误 [无法访问 jarfile server.port]
- angular - Angular 7+ - 注入和子类
- scala - 如何在 Scala Spark 中设计一个抽象阅读器?
- css - 覆盖引导类“导航项”
- c++ - 无法使用 Adafruit Motor Shield V2.3 驱动直流电机
- visual-studio-code - Visual Studio 代码 & gulp