当前位置: 首页 > news >正文

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

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

v拆分JSON字符串​

1.1按结构拆分​

数组拆分​​:若JSON包含大型数组,可将其拆分为多个小数组。

// 示例:将大数组拆分为多个子数组
JSONArray bigArray = new JSONArray(jsonString);
int chunkSize = 100;
for (int i = 0; i < bigArray.length(); i += chunkSize) {JSONArray chunk = new JSONArray();for (int j = i; j < Math.min(i + chunkSize, bigArray.length()); j++) {chunk.put(bigArray.get(j));}String chunkJson = chunk.toString();// 处理或保存chunkJson
}

​​对象拆分​​:若JSON是嵌套对象,可按层级拆分为子对象。

1.2按大小拆分(流式处理)​​

使用流式API(如Jackson的JsonParser)逐块读取JSON内容,避免一次性加载到内存:

JsonFactory factory = new JsonFactory();
try (JsonParser parser = factory.createParser(new File("large.json"))) {while (parser.nextToken() != null) {// 逐Token处理,如按特定条件拆分
    }
}

v压缩JSON字符串​

2.1使用GZIP压缩​
import java.util.zip.GZIPOutputStream;
import java.io.ByteArrayOutputStream;public static byte[] compress(String data) throws IOException {ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length());try (GZIPOutputStream gzip = new GZIPOutputStream(bos)) {gzip.write(data.getBytes());}return bos.toByteArray();
}// 压缩后的数据可用于传输或存储
byte[] compressed = compress(jsonString);
2.2使用Deflater压缩​
import java.util.zip.Deflater;public static byte[] deflateCompress(String data) {Deflater deflater = new Deflater();deflater.setInput(data.getBytes());deflater.finish();byte[] buffer = new byte[1024];ByteArrayOutputStream outputStream = new ByteArrayOutputStream();while (!deflater.finished()) {int count = deflater.deflate(buffer);outputStream.write(buffer, 0, count);}deflater.end();return outputStream.toByteArray();
}

v优化JSON体积​​

3.1移除无用空格​

使用紧凑格式(无缩进、换行):

new JSONObject(jsonString).toString(); // 默认紧凑格式
3.2​​缩短键名​

将长字段名替换为短名称:

{"n":"Alice","a":30} // 原始键名可能为"name"、"age"

v流式处理大型JSON​​

使用流式API逐步解析,避免内存溢出:

// Jackson流式API示例
JsonFactory factory = new JsonFactory();
try (JsonParser parser = factory.createParser(new File("large.json"))) {JsonToken token;while ((token = parser.nextToken()) != null) {if (token == JsonToken.START_ARRAY) {while (parser.nextToken() != JsonToken.END_ARRAY) {// 逐条处理数组元素JsonNode node = parser.readValueAsTree();// 处理node...
            }}}
}

v分页处理​

其实也是拆分,将数据拆成若干份

v实践方案

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;public class CompressHelper {private static final ObjectMapper objectMapper = new ObjectMapper();/*** 方式1:去除JSON中的空格/换行等冗余字符(文本压缩)* @param formattedJson 格式化的JSON字符串(含空格换行)* @return 紧凑格式的JSON字符串* @throws IOException JSON解析异常*/public static String compressJsonByRemovingSpaces(String formattedJson) throws IOException {JsonNode jsonNode = objectMapper.readTree(formattedJson);return objectMapper.writeValueAsString(jsonNode);}/*** 方式2:使用GZIP算法对JSON字符串进行二进制压缩(适合网络传输)* @param json 原始JSON字符串* @return Base64编码的压缩后字符串(可直接传输)* @throws IOException 压缩异常*/public static String compressJsonByGzip(String json) throws IOException {try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream();GZIPOutputStream gzipOut = new GZIPOutputStream(byteOut)) {gzipOut.write(json.getBytes("UTF-8"));gzipOut.finish();return Base64.encodeBase64String(byteOut.toByteArray());}}public static String decompressJson(String source) throws IOException {byte[] compressedData = Base64.decodeBase64(source);try (ByteArrayInputStream byteIn = new ByteArrayInputStream(compressedData);GZIPInputStream gzipIn = new GZIPInputStream(byteIn);ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) {// 读取压缩数据并解压缩byte[] buffer = new byte[1024];int len;while ((len = gzipIn.read(buffer)) != -1) {byteOut.write(buffer, 0, len);}return byteOut.toString(StandardCharsets.UTF_8.name());}}
}

v源码地址

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


作  者:请叫我头头哥
出  处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!

http://www.hskmm.com/?act=detail&tid=26903

相关文章:

  • 塑料回收技术创新与可持续发展
  • 共享掩码:TFHE在打包消息上的自举技术
  • 详细介绍:[论文阅读] (38)基于大模型的威胁情报分析与知识图谱构建论文总结(读书笔记)
  • MATLAB安装 - -一叶知秋
  • 2025球墨铸铁管厂家 TOP 企业品牌推荐排行榜,市政球墨铸铁管、球墨铸铁管件、防腐球墨铸铁管、给水球墨铸铁管推荐这十家公司!
  • Say 题选记(10.5 - 10.11)
  • E. Rasta Thamaye Dilo
  • 微信机器人开发最新协议API
  • JDK的安装与使用 - XYX
  • Rust 的英文数字验证码识别系统实现
  • 微信机器人制作教程+源码
  • 基于 Rust 的英文数字验证码识别系统实现
  • 使用 Fortran 实现英文数字验证码识别系统
  • 初来乍到,发篇博客试试功能
  • 国庆集训游记
  • P11967 [GESP202503 八级] 割裂
  • 用 Ada 实现英文数字验证码识别
  • P11380 [GESP202412 八级] 排队
  • 数据增强操作
  • HTML5实现简洁的端午节节日网站源码 - 实践
  • Visio的图片,粘到word中显示不全,右边和下面显示不出来
  • 25国庆总结
  • 某平台增强排序脚本
  • 印度乡村AI计划:用JAN AI打造人工智能优先村庄
  • # Java方法学习:动手动脑与课后实验整理
  • CF2155D Batteries
  • JAVA语法基础》动手动脑与实验问题全整理
  • 崩铁壁纸
  • PotPlayer 播放器
  • 10.8动手动孬