找回密码
 立即注册
首页 业界区 业界 SpringBoot进阶教程(八十七)数据压缩

SpringBoot进阶教程(八十七)数据压缩

坏级尹 前天 22:20
最近在使用Redis的时候,经常遇到一些不常用的大key,对存储有一些负担。就想着把大key压缩一下。压缩可以分很多种,比如拆分JSON字符串​, ​​压缩JSON字符串​,优化JSON体积​,流式处理大型JSON​和分段存储。
v拆分JSON字符串​

1.1按结构拆分​数组拆分​​:若JSON包含大型数组,可将其拆分为多个小数组。
  1. // 示例:将大数组拆分为多个子数组
  2. JSONArray bigArray = new JSONArray(jsonString);
  3. int chunkSize = 100;
  4. for (int i = 0; i < bigArray.length(); i += chunkSize) {
  5.     JSONArray chunk = new JSONArray();
  6.     for (int j = i; j < Math.min(i + chunkSize, bigArray.length()); j++) {
  7.         chunk.put(bigArray.get(j));
  8.     }
  9.     String chunkJson = chunk.toString();
  10.     // 处理或保存chunkJson
  11. }
复制代码
​​对象拆分​​:若JSON是嵌套对象,可按层级拆分为子对象。
1.2按大小拆分(流式处理)​​使用流式API(如Jackson的JsonParser)逐块读取JSON内容,避免一次性加载到内存:
  1. JsonFactory factory = new JsonFactory();
  2. try (JsonParser parser = factory.createParser(new File("large.json"))) {
  3.     while (parser.nextToken() != null) {
  4.         // 逐Token处理,如按特定条件拆分
  5.     }
  6. }
复制代码
v压缩JSON字符串​

2.1使用GZIP压缩​
  1. import java.util.zip.GZIPOutputStream;
  2. import java.io.ByteArrayOutputStream;
  3. public static byte[] compress(String data) throws IOException {
  4.     ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length());
  5.     try (GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
  6.         gzip.write(data.getBytes());
  7.     }
  8.     return bos.toByteArray();
  9. }
  10. // 压缩后的数据可用于传输或存储
  11. byte[] compressed = compress(jsonString);
复制代码
2.2使用Deflater压缩​
  1. import java.util.zip.Deflater;
  2. public static byte[] deflateCompress(String data) {
  3.     Deflater deflater = new Deflater();
  4.     deflater.setInput(data.getBytes());
  5.     deflater.finish();
  6.     byte[] buffer = new byte[1024];
  7.     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  8.     while (!deflater.finished()) {
  9.         int count = deflater.deflate(buffer);
  10.         outputStream.write(buffer, 0, count);
  11.     }
  12.     deflater.end();
  13.     return outputStream.toByteArray();
  14. }
复制代码
v优化JSON体积​​

3.1移除无用空格​使用紧凑格式(无缩进、换行):
  1. new JSONObject(jsonString).toString(); // 默认紧凑格式
复制代码
3.2​​缩短键名​将长字段名替换为短名称:
  1. {"n":"Alice","a":30} // 原始键名可能为"name"、"age"
复制代码
v流式处理大型JSON​​

使用流式API逐步解析,避免内存溢出:
  1. // Jackson流式API示例
  2. JsonFactory factory = new JsonFactory();
  3. try (JsonParser parser = factory.createParser(new File("large.json"))) {
  4.     JsonToken token;
  5.     while ((token = parser.nextToken()) != null) {
  6.         if (token == JsonToken.START_ARRAY) {
  7.             while (parser.nextToken() != JsonToken.END_ARRAY) {
  8.                 // 逐条处理数组元素
  9.                 JsonNode node = parser.readValueAsTree();
  10.                 // 处理node...
  11.             }
  12.         }
  13.     }
  14. }
复制代码
v分页处理​

其实也是拆分,将数据拆成若干份
v实践方案
  1. import com.fasterxml.jackson.databind.JsonNode;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import java.io.ByteArrayInputStream;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.IOException;
  6. import java.util.zip.GZIPInputStream;
  7. import java.util.zip.GZIPOutputStream;
  8. import org.apache.commons.codec.binary.Base64;
  9. import java.nio.charset.StandardCharsets;
  10. public class CompressHelper {
  11.     private static final ObjectMapper objectMapper = new ObjectMapper();
  12.     /**
  13.      * 方式1:去除JSON中的空格/换行等冗余字符(文本压缩)
  14.      * @param formattedJson 格式化的JSON字符串(含空格换行)
  15.      * @return 紧凑格式的JSON字符串
  16.      * @throws IOException JSON解析异常
  17.      */
  18.     public static String compressJsonByRemovingSpaces(String formattedJson) throws IOException {
  19.         JsonNode jsonNode = objectMapper.readTree(formattedJson);
  20.         return objectMapper.writeValueAsString(jsonNode);
  21.     }
  22.     /**
  23.      * 方式2:使用GZIP算法对JSON字符串进行二进制压缩(适合网络传输)
  24.      * @param json 原始JSON字符串
  25.      * @return Base64编码的压缩后字符串(可直接传输)
  26.      * @throws IOException 压缩异常
  27.      */
  28.     public static String compressJsonByGzip(String json) throws IOException {
  29.         try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
  30.              GZIPOutputStream gzipOut = new GZIPOutputStream(byteOut)) {
  31.             gzipOut.write(json.getBytes("UTF-8"));
  32.             gzipOut.finish();
  33.             return Base64.encodeBase64String(byteOut.toByteArray());
  34.         }
  35.     }
  36.     public static String decompressJson(String source) throws IOException {
  37.         byte[] compressedData = Base64.decodeBase64(source);
  38.         try (ByteArrayInputStream byteIn = new ByteArrayInputStream(compressedData);
  39.              GZIPInputStream gzipIn = new GZIPInputStream(byteIn);
  40.              ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) {
  41.             // 读取压缩数据并解压缩
  42.             byte[] buffer = new byte[1024];
  43.             int len;
  44.             while ((len = gzipIn.read(buffer)) != -1) {
  45.                 byteOut.write(buffer, 0, len);
  46.             }
  47.             return byteOut.toString(StandardCharsets.UTF_8.name());
  48.         }
  49.     }
  50. }
复制代码
v源码地址

https://github.com/toutouge/javademosecond/tree/master/hellolearn

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册