Java中如何计算JsonNode的字节/KB/MB大小?
Java中计算JSON字节大小的实现方案
现有写法的准确性说明
你当前使用的jsonResponse.toString().getBytes().length方法存在两个可控的误差点,调整后可以满足需求:
- 无参
getBytes()会使用JVM默认编码,而JSON规范默认采用UTF-8编码,PostgreSQL计算JSON相关字段大小也默认用UTF-8,编码不一致会直接导致结果偏差 JsonNode.toString()的输出规则如果和PostgreSQL侧的JSON序列化规则不一致(比如转义策略、空格换行、键顺序等),也会出现大小差异
Jackson原生的精准计算方法
推荐直接使用Jackson的序列化能力直接生成UTF-8字节流计算大小,避免中间String转换的额外开销和误差:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; // 全局复用ObjectMapper实例即可 private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); // 计算JSON UTF-8字节数 public long getJsonByteSize(JsonNode jsonNode) throws Exception { byte[] jsonBytes = OBJECT_MAPPER.writeValueAsBytes(jsonNode); return jsonBytes.length; } // 单位转换 public double toKB(long byteSize) { return byteSize / 1024.0; } public double toMB(long byteSize) { return byteSize / (1024.0 * 1024); }
如果要处理超大JSON,不想将全量字节加载到内存,可以用计数输出流统计大小,避免内存占用过高:
import org.apache.commons.io.output.CountingOutputStream; public long getLargeJsonByteSize(JsonNode jsonNode) throws Exception { try (CountingOutputStream cos = new CountingOutputStream(OutputStream.nullOutputStream())) { OBJECT_MAPPER.writeValue(cos, jsonNode); return cos.getCount(); } }
和PostgreSQL pg_column_size结果对齐的注意事项
- 若PostgreSQL存储的是
json类型:pg_column_size()返回的是原始JSON文本的UTF-8字节数加少量存储头开销,如需对比纯JSON文本大小,可在PostgreSQL侧用length(json_column::text)计算,和Java侧结果对齐 - 若PostgreSQL存储的是
jsonb类型:pg_column_size()返回的是jsonb二进制结构的存储占用,和JSON文本大小不一致,同样使用length(jsonb_column::text)计算文本侧大小即可 - 确保两侧序列化规则一致:比如关闭Jackson的非ASCII字符转义配置
OBJECT_MAPPER.configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), false),保持和PostgreSQL的转义规则统一
内容的提问来源于stack exchange,提问作者Magi
相关产品推荐
相关产品推荐

