如何读取Brotli压缩字符串?网站压缩JSON串读取疑问
Brotli压缩JSON解压问题:从String转流失败的原因与解决办法
嗨,这个问题我碰到过好几次啦!核心原因其实很简单:你把二进制的Brotli压缩数据错误地当成UTF-8文本转成了String,这直接破坏了原始的压缩字节流。
为什么直接用响应输入流没问题?
当你用response.getEntity().getContent()获取输入流时,拿到的是服务器返回的原始二进制压缩数据,直接传给BrotliInputStream就能正确识别并解压,整个过程没有对字节做任何编码转换,自然正常工作。
转成String后为什么会失败?
String是专门用来存储文本内容的,当你用IOUtils.toInputStream(responseAsString, "UTF-8")的时候,相当于做了两步错误操作:
- 先把二进制压缩数据用UTF-8解码成String——但Brotli压缩后的字节根本不是合法的UTF-8文本,解码过程中会把无法识别的字节替换成默认的�(替换字符),导致原始数据丢失。
- 再把这个损坏的String转成输入流,此时传给
BrotliInputStream的已经不是原来的压缩数据了,解压自然会报错或者得到乱码。
正确的解决办法:用字节数组保存原始压缩数据
不要把压缩数据转成String,直接用字节数组存储原始二进制内容,之后再转成输入流解压:
// 第一步:获取原始压缩字节数组,跳过String转换 byte[] compressedData = IOUtils.toByteArray(response.getEntity().getContent()); // 第二步:用字节数组创建输入流,再进行Brotli解压 BufferedReader rd = new BufferedReader( new InputStreamReader( new BrotliInputStream(new ByteArrayInputStream(compressedData)), "UTF-8" ) ); StringBuilder result = new StringBuilder(); String line; while ((line = rd.readLine()) != null) { result.append(line); } // 记得关闭流 rd.close(); // 现在result里就是完整的解压后JSON字符串了
额外提醒
以后碰到二进制数据(压缩包、图片、加密内容等),都要避免用String存储,一定要用字节数组或者直接操作字节流,否则很容易因为编码问题损坏数据。
内容的提问来源于stack exchange,提问作者Abhash Upadhyaya
相关产品推荐
相关产品推荐

