将hexdump命令转换为Format-Hex时遭遇编码问题求助
问题原因分析
你看到的EF BF BD是**Unicode替换字符(U+FFFD)**的UTF-8编码,根源在于:
- 外部命令
protoc输出的字节流里包含0x80,这个字节不属于ASCII范围,且单独出现时不符合UTF-8编码规则(UTF-8中0x80只能作为多字节序列的续字节)。 - PowerShell默认会用
[Console]::OutputEncoding将外部命令的字节输出解码为字符串,遇到无法识别的字节时,会自动用U+FFFD替换,导致后续用Format-Hex处理字符串时,显示的是替换字符的UTF-8编码,而非原始的0x80。 - 而
0x08(退格)和0x7F(删除)属于ASCII控制字符,能被正常解码,所以之前的测试能得到正确结果。
解决方法
要保留原始字节流,避免PowerShell自动解码,直接捕获外部命令的输出字节再处理:
方法1:使用System.Diagnostics.Process捕获原始字节
# 配置进程信息 $procStartInfo = [System.Diagnostics.ProcessStartInfo]@{ FileName = "protoc" Arguments = "你的命令参数" # 替换为实际protoc执行参数 RedirectStandardOutput = $true UseShellExecute = $false CreateNoWindow = $true } # 启动进程并捕获输出字节 $proc = [System.Diagnostics.Process]::Start($procStartInfo) $stdoutBytes = $proc.StandardOutput.BaseStream.ReadAllBytes() $proc.WaitForExit() # 查看原始字节的十六进制 $stdoutBytes | Format-Hex
方法2:临时修改输出编码(适用于单字节编码场景)
如果protoc输出的是单字节编码(比如Latin-1),可以临时修改$OutputEncoding让PowerShell正确解码:
# 临时设置输出编码为Latin-1(单字节编码,支持所有0x00-0xFF字节映射) $originalEncoding = $OutputEncoding $OutputEncoding = [System.Text.Encoding]::Latin1 # 执行protoc并捕获输出,此时0x80会被解码为对应Latin-1字符 $output = & protoc 你的命令参数 # 转回原始字节并查看十六进制 [System.Text.Encoding]::Latin1.GetBytes($output) | Format-Hex # 恢复原编码 $OutputEncoding = $originalEncoding
验证测试
用你提供的字节数组测试逻辑正确性:
# 模拟protoc输出的字节流 $testBytes = [byte[]]@(0x08, 0x80, 0x01) $testBytes | Format-Hex
输出会正确显示:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 08 80 01 ...
内容的提问来源于stack exchange,提问作者Clément Jean
相关产品推荐
相关产品推荐

