最稳妥方式是用 os.readfile 读取文件字节后调用 hex.encodetostring 转小写十六进制字符串;大文件需分块读取并用 strings.builder 拼接;fmt.sprintf("%x", data) 会误打印切片头而非内容。

用 fmt.Sprintf 和 hex.EncodeToString 最稳妥
直接读文件字节再转十六进制字符串,别自己写循环拼接。Go 标准库的 hex.EncodeToString 不仅安全、高效,还自动处理边界和大小写——它输出小写十六进制,若需大写,得额外调用 strings.ToUpper。
常见错误是误用 fmt.Sprintf("%x", data):它对 []byte 会打印切片头信息(类似 [0xc000010240 10]),不是内容本身;必须先转成 []byte 再传给 hex.EncodeToString。
- 先用
os.ReadFile一次性读取(适合中小文件;大文件请用流式处理) - 检查返回 error,空文件也会返回
nil数据但不报错 -
hex.EncodeToString输入是[]byte,输出是string,无额外换行或分隔符
data, err := os.ReadFile("example.txt")
if err != nil {
log.Fatal(err)
}
hexStr := hex.EncodeToString(data) // 小写,如 "68656c6c6f"
读大文件时不能全加载进内存
超过几十 MB 的文件,os.ReadFile 容易触发 OOM。此时应边读边转,用 bufio.Reader 或直接操作 *os.File + make([]byte, chunkSize) 分块读取。
注意:hex.EncodeToString 只接受完整字节切片,不能“追加编码”。所以每块要单独转,再拼接字符串——但频繁字符串拼接影响性能,建议用 strings.Builder。
- 推荐 chunkSize 设为 4096 或 8192,兼顾 IO 效率与内存占用
- 最后一块可能不足 chunkSize,
read返回实际长度,别直接用 full buffer - 不要用
+=拼接 hex 字符串,尤其在循环中
var builder strings.Builder
buf := make([]byte, 4096)
for {
n, err := file.Read(buf)
if n > 0 {
builder.WriteString(hex.EncodeToString(buf[:n]))
}
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
}
hexStr := builder.String()
十六进制字符串要不要加空格或换行?
标准 hex.EncodeToString 输出是紧凑字符串(如 "666f6f626172"),没有分隔。如果用于调试展示,需要每 2 字符加空格、每 32 字符换行,就得自己格式化。
容易踩的坑是正则替换或字符串切片时索引越界,尤其最后不足 2 字符的尾部。更稳的方式是遍历字节,按位置插入分隔符。
- 每两个字符后加空格:用
for i := 0; i ,注意 <code>i+2 - 避免用
strings.ReplaceAll(s, "", " ")这类错误写法 - 终端显示宽度过长时,换行逻辑要基于 hex 字符数(不是原始字节数)计算
Windows 下读取文本文件可能遇到 BOM
UTF-8 编码的文本文件若带 BOM(EF BB BF),会出现在 hex 字符串开头。这不是 bug,是文件真实内容。若业务要求去除 BOM,得在转 hex 前判断并截断。
别依赖文件扩展名或声明判断编码——BOM 是二进制层面的存在,os.ReadFile 返回的就是原始字节,BOM 就在那里。
- 检查前 3 字节是否等于
[]byte{0xef, 0xbb, 0xbf} - 只对 UTF-8 BOM 做处理;UTF-16/32 BOM 更少见,按需支持
- 去掉 BOM 后再转 hex,否则 hex 字符串开头会多出
"efbbbf"
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











