You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用serde_json传输Vec<u8>时,base64编码能否节省空间?

问题分析与解决方案

为什么字节数会膨胀三倍?

你猜的方向没错,但更准确的原因是:serde_json默认会把Vec<u8>里的每个字节序列化为十进制数字字符串。比如单个字节0xFF会被转成字符串"255",占3个UTF-8字节;哪怕是小数值如0x01,也会变成"1"占1字节,平均下来每个字节会占用2-3个字符,400字节的原始数据自然会膨胀到1200左右,正好是三倍的量级。

你用serde_bytes没效果,大概率是没给Vec<u8>字段加上对应的序列化注解——默认情况下serde_bytes不会自动接管Vec<u8>的序列化,还是会按普通JSON数组处理,字节数自然还是一样膨胀。

你的字节统计方式是对的

serde_json::to_value(content).to_string().to_bytes().len()这个统计逻辑是准确的:因为最终通过reqwest发送JSON时,传输的就是这个序列化后的UTF-8字符串的字节数,完全能反映实际请求的大小,用来预判接口限制没问题。

可行的解决方案

1. 用Base64编码(推荐)

这是二进制数据在JSON里传输的标准做法,开销远低于原生数组序列化。你可以用serde_with库的Base64注解自动处理序列化和反序列化,不用手动转:

use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use serde_with::base64::Base64;

#[serde_as]
#[derive(Serialize, Deserialize)]
struct MyRequest {
    #[serde_as(as = "Base64")]
    content: Vec<u8>,
}

// 序列化时自动转base64,反序列化自动转回Vec<u8>
let req = MyRequest { content: vec![0u8; 400] };
let json_str = serde_json::to_string(&req).unwrap();
println!("Serialized length: {}", json_str.as_bytes().len()); // 约500字节左右

这样既解决了字节膨胀问题,又省去了手动处理编码解码的繁琐步骤。

2. 正确使用serde_bytes(不推荐,字节开销仍大)

如果坚持要用JSON数组形式,得给Vec<u8>加上serde_bytes的注解,让它按优化后的逻辑序列化数字数组,但本质还是每个字节转成字符串形式,字节数还是会膨胀到1200左右,对你的接口限制来说没帮助,所以不推荐:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct MyRequest {
    #[serde(with = "serde_bytes")]
    content: Vec<u8>,
}

内容的提问来源于stack exchange,提问作者NoKey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:33:27