C#将文件转换为十六进制字符串 C#如何获取文件的Hex Dump

1次阅读

C#将文件转换为十六进制字符串 C#如何获取文件的Hex Dump

File.ReadAllBytes 读取文件再转十六进制字符串

这是最直接的方式:先读取整个文件为字节数组,再逐字节格式化为两位十六进制字符。适合中小文件(

常见错误是用 Encoding.UTF8.GetString 后再调用 GetBytes —— 这会破坏原始二进制内容,完全不可取。

  • File.ReadAllBytes(path) 返回 byte[],保持原始字节不变
  • string.Join("", bytes.Select(b => b.ToString("x2"))) 转成小写十六进制字符串(如 "48656c6c6f"
  • 若需大写,改用 "X2" 格式(如 "48656C6C6F"
  • 不建议对超大文件一次性读入内存,会触发 OutOfMemoryException

大文件用 FileStream + Span<byte></byte> 流式处理

当文件超过几百 MB,必须避免全量加载。用 FileStream 分块读取,配合 Span<byte></byte> 避免重复分配数组,性能更稳。

注意:别用 StreamReader 或任何基于文本的流——它们会尝试解码,彻底毁掉二进制数据。

  • 创建 FileStream 时指定 FileAccess.ReadFileShare.Read
  • 分配一个固定大小的 byte[] buffer = new byte[8192],或用 stackalloc byte[8192](仅限 unsafe 上下文)
  • 循环调用 stream.Read(buffer, 0, buffer.Length),直到返回值为 0
  • 每块用 Span<byte>.Slice(0, bytesRead).SequenceEqual(...)</byte> 不需要,只需对当前块做 ToString("x2") 拼接

输出带地址偏移和 ASCII 显示的类 unix Hex Dump

如果目标是模拟 xxdhexdump -C 的可读格式(含偏移、十六进制区、ASCII 区),就不能只拼字符串,得按行组织。

典型坑是 ASCII 区乱码处理:非打印字符(0x00–0x1F0x7F)应显示为 .,空格和换行等要保留语义。

  • 每行通常 16 字节,偏移用 8 位十六进制左对齐(如 "00000000: "
  • 十六进制部分每字节两个字符,每 4 字节加空格分隔("48656c6c 6f20776f..."
  • ASCII 区:对每个字节 b,判断 char.IsControl((char)b) || b > 127,是则填 '.',否则转 (char)b
  • 最后一行可能不满 16 字节,ASCII 区右侧补空格对齐

注意编码与 bom 对结果的影响

Hex dump 是对原始字节的忠实呈现,跟文本编码无关。但如果你误用 File.ReadAllText 再转字节,就会引入编码层干扰——比如 UTF-8 BOM(0xEF,0xBB,0xBF)会被自动剥离或错误解释。

哪怕文件本身是纯文本,只要需求是“Hex Dump”,就必须绕过所有编码逻辑,直触字节流。

  • 绝对不要用 File.ReadAllTextStreamReaderEncoding.default
  • 确认路径存在且有读取权限,否则 File.ReadAllBytesFileNotFoundExceptionUnauthorizedAccessException
  • linux/macos 路径区分大小写,C:test.txtc:test.txtwindows 下等价,但代码里保持一致更安全

实际 Hex Dump 的复杂点不在转换本身,而在格式对齐、边界处理和不可见字符的判定逻辑。很多人卡在最后一行补空格或 ASCII 区错位上,建议先写单行逻辑验证,再扩展成完整块渲染。

text=ZqhQzanResources