比如字符串“非 是 非 - noyesno ”内部表示(Unicode BE)为:
975e 0020 662f 0020 975e 0020 002d 0020 006e 006f 0079 0065 0073 006e 006f
encoding system utf-8 set data "非 是 非 - noyesno" set file "out.txt" set fout [open $file "w"] puts -nonewline $fout $data close $fout puts "size = [file size $file]" exec xxd $file >@ stdout
输出文件正常,字符采用了系统默认编码"utf-8"。
另外尝试一下几种编码设置:
fconfigure $fout -encoding binary
fconfigure $fout -translation binary
fconfigure $fout -encoding utf-8
只有第三种设置输出正常,其他几种均出现乱码或者内容错误。
先说结论:
-translation binary
会自动设置-encoding binary
-encoding binary
的效果是把每一个字符(两个字节)作为一个字节输出(低位字节)。
需要以二进制形式输出数据时:
-encoding binary
选项。-translation binary
选项上述任一项设置都会导致-encoding binary
,进而出现上面提到的高位字节丢失问题。
因此需要输出二进制数据时需要预先转换编码:
set data [encoding convertto $data] puts -nonewline $sock $data ;# 注意使用 -nonewline 选项
额外需要注意使用 -nonewline 选项,以避免添加额外的字符。
比如,通讯协议要求了,先传输数据长度(字节数),再传输数据内容。这时需要:
这在涉及数据结构的编程(网络通讯,二进制数据文件)中很重要。
TODO