Java读取音频转Base64应优先用Files.readAllBytes获取字节数组,避免字符流乱码;大文件需流式编码防OOM;解码前须清理空白符并剥离data:前缀;还原时需确保字节完全一致。

Java读取音频文件并转Base64字符串
直接用 java.util.Base64 编码二进制流是最稳妥的方式,避免第三方库引入兼容性问题。关键不是“怎么转”,而是“别用错字节读取方式”——比如用 Files.readString() 读音频会乱码,必须走字节数组。
- 务必使用
Files.readAllBytes(Paths.get("xxx.mp3"))获取原始字节,不能用字符流 - Base64编码后字符串可直接存数据库、传HTTP参数或嵌入HTML的
标签 - 注意大文件(>10MB)可能触发JVM堆溢出,需分块读取(见下一条)
处理大音频文件时避免内存溢出
一次性读取几百MB的WAV文件到内存,OutOfMemoryError 几乎必然发生。这时候不能硬编码 readAllBytes,得用流式编码。
- 用
Base64.getEncoder().wrap(OutputStream)包装目标输出流(如ByteArrayOutputStream或文件) - 配合
InputStream分段读取(建议每次8192字节),再写入Base64包装流 - 最终从
ByteArrayOutputStream取toString("UTF-8")得到Base64字符串
InputStream is = Files.newInputStream(Paths.get("large.wav"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream base64Out = Base64.getEncoder().wrap(baos);
byte[] buf = new byte[8192];
int len;
while ((len = is.read(buf)) != -1) {
base64Out.write(buf, 0, len);
}
base64Out.close(); // 必须调用,否则末尾填充=可能缺失
String base64Str = baos.toString("UTF-8");
Base64字符串还原为音频文件
解码比编码更易出错:常见问题是字符串被截断、含不可见空格、换行符(尤其从HTTP POST或日志里复制时),导致 IllegalArgumentException: Illegal base64 character。
- 先用
string.replaceAll("[\\s]", "")清除所有空白符(包括\r\n\t) - 校验长度是否为4的倍数,不足则补等号(但一般Base64库会自动容忍)
- 用
Base64.getDecoder().decode(string)得到字节数组,再用Files.write()写入磁盘 - 务必指定原始音频扩展名(如
.mp3),否则系统无法识别格式
在Spring Boot中接收Base64音频并保存
前端传来的Base64常带前缀,如 data:audio/wav;base64,UEsDB...,不剥离会解码失败。
立即学习“Java免费学习笔记(深入)”;
- 检查字符串是否以
data:开头,是则用substring(indexOf(",") + 1)截取纯Base64部分 - 注意MIME类型只是提示,真正决定文件格式的是二进制内容,解码后写成
.wav还是.mp3要和前端约定好 - 保存路径建议用
Paths.get(uploadDir, UUID.randomUUID() + ".wav")防重名
最容易被忽略的是:Base64解码后的字节必须和原始音频完全一致,哪怕差一个字节,播放器也会报“文件损坏”。所以做一次 round-trip(编码→解码→对比MD5)验证是有必要的。










