base64转换核心是字节流原样进出:字符串必须先用utf-8编码为byte[]再编码,解码前需清理空白、补全填充并处理base64url变体,二进制文件须直接读取字节,还原时须用writeallbytes而非文本写入。

直接用 Convert.ToBase64String 和 Convert.FromBase64String 就能完成,但 90% 的失败不是方法错了,而是字节转换这一步被跳过、选错或没清理输入。
字符串转 Base64 必须先走 UTF-8 字节数组
Convert.ToBase64String 只接受 byte[],不接受 string。试图传字符串会编译报错。
- 正确做法:用
Encoding.UTF8.GetBytes("你好")得到字节数组,再喂给Convert.ToBase64String - 别用
Encoding.Default—— 它依赖系统区域设置,部署到 Linux 或不同语言 Windows 上大概率乱码 - 中文、emoji、特殊符号必须走 UTF-8;ASCII 字符虽可用
Encoding.ASCII,但混用时极易出错,统一用 UTF-8 最稳妥 - 示例:
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes("Hello 世界"));→SGVsbG8g5L2g5aW9
Base64 解码前必须清理空白和补全填充
Convert.FromBase64String 对非法字符零容忍,遇到空格、换行、长度非 4 倍数会直接抛 FormatException。
- 常见来源(表单提交、日志粘贴、HTTP header)常带
、空格或制表符,先调用.Replace(" ", "").Replace(" ", "").Replace(" ", "") - URL 场景下可能用
-替代+、_替代/(即 Base64Url 编码),需先还原:.Replace('-', '+').Replace('_', '/') - 末尾等号
=可能被截断,检查长度 % 4:若余 1 → 补 3 个=;余 2 → 补 2 个;余 3 → 补 1 个;余 0 → 不补(实际常用.PadRight(len + (4 - len % 4) % 4, '=')) - 务必用
try/catch包裹解码逻辑,避免上游数据异常导致整个流程崩溃
图片/文件转 Base64 别碰 StreamReader,直接读二进制
图片、PDF、ZIP 等二进制文件不能当文本读,否则字节损坏,解码后文件打不开。
- 安全做法:用
File.ReadAllBytes(@"path.jpg")直接获取原始字节,再调用Convert.ToBase64String - 路径含反斜杠时,必须用
@前缀或双写\,否则会被解析为制表符 - 大文件(>100MB)慎用
ReadAllBytes—— 内存占用会膨胀至约 133%,容易触发OutOfMemoryException - 若必须处理大文件,分块读取 FileStream,每次最多处理 3072 字节原始数据(对应 4096 字节 Base64 输出),拼接结果
从 Base64 还原图片/文件时,字节必须原样写出
解码得到的 byte[] 是原始二进制,不能再经过任何字符串编码中转,否则文件结构被破坏。
- 错误写法:
File.WriteAllText(path, Encoding.UTF8.GetString(bytes))—— 这会把二进制当文本写,图片直接变花 - 正确写法:
File.WriteAllBytes(path, Convert.FromBase64String(base64)) - 如果 Base64 来自 data URL(如
data:image/png;base64,iVBORw...),必须先用.Substring()或正则剔除前缀,只留纯 Base64 部分 - 写入前检查目标路径是否存在父目录,
Directory.CreateDirectory(Path.GetDirectoryName(path))避免DirectoryNotFoundException
最容易被忽略的是:Base64 不是加密,只是编码;所有操作都建立在“字节流原样进出”这个前提上。一旦在字符串 ↔ 字节之间用了不一致的编码,或对二进制数据做了文本化处理,就再也无法还原原始内容。











