




Base64编码将二进制数据转为ASCII字符串以适配文本协议;Java中三种编码器适用场景不同:标准版用于通用场景,URL版适配URL参数,MIME版仅用于邮件附件;需严格保证编解码时字符集一致,避免乱码;大文件应流式处理以防OOM。
Java 的 java.util.Base64 类不是为“加密”或“压缩”设计的,它的核心作用是把任意字节序列(比如图片、PDF、密钥)转换成只含 ASCII 可见字符(A–Z, a–z, 0–9, +, /, =)的字符串。这样就能塞进 HTTP Header、JSON 字段、URL 参数、XML 内容等原本只接受文本的地方,避免乱码、截断或协议解析失败。
Base64.getEncoder()、Base64.getUrlEncoder() 和 Base64.getMimeEncoder() 都输出 Base64 字符串,但替换规则和填充行为不同,直接影响能否被下游正确解析:
getEncoder():标准 RFC 4648 表达,用 + 和 /,末尾补 =;适合通用 Java 内部处理或非 URL 场景getUrlEncoder():把 + 换成 -,/ 换成 _,不补 =(可选);必须用于 URL 路径、查询参数或 Cookie 值,否则会被服务器误解析getMimeEncoder():每 76 字符换行(\r\n),严格遵循 MIME 标准;仅在构造邮件附件或旧式 MIME 流时需要,Web 开发几乎不用错误示例:把 getEncoder().encodeToString(bytes) 的结果直接拼进 URL,遇到 + 会被当成空格,/ 可能触发路由匹配异常。
Base64 是纯编码,不改变原始语义,但 Java 中的字符串编码(String.getBytes())默认依赖平台 Charset,极易导致解码失败:
byte[] original = "你好".getBytes(StandardCharsets.UTF_8); // ✅ 明确指定 UTF-8 String encoded = Base64.getEncoder().encodeToString(original); // 解码端必须用同样逻辑: byte[] decoded = Base64.getDecoder().decode(encoded); String restored = new String(decoded, StandardCharsets.UTF_8); // ✅ 同样指定 UTF-8
常见坑:
StandardCharsets.UTF_8,用 "你好".getBytes() → Windows 上可能走 GBK,Linux 上走 UTF-8,编码端和解码端不一致就还原出乱码new String(base64Str.getBytes(), ...) 多套一层,引入无谓的字符集转换Base64.getDecoder().decode(String) 时传入含空格、换行、BOM 的字符串 → 抛 IllegalArgumentException: Illegal base64 character
Base64 类是线程安全的,但每次调用 encodeToString() 都会新建 String,而 Base64 编码后体积膨胀约 33%(4 字节编码为 3 字节原始数据)。大文件(如 >1MB)直接全量编码容易触发 GC 或 OOM:
encoder.encode(byte[], int, int) + ByteBuffer 流式处理Base64.Encoder 实例 —— 它是无状态的,复用静态实例即可(Base64.getEncoder() 返回单例)android.util.Base64 或第三方库(如 Apache Commons Codec)真正麻烦的从来不是“能不能编”,而是“编完谁来解、在哪解、用什么字符集解”。只要原始字节来源和目标解析环境的编码约定没对齐,Base64 就只是把问题从传输层转移到了语义层。