从二进制文件中读取错误的字节数

时间:2017-05-20 17:53:36

标签: tcl

我有以下代码:

set myfile "the path to my file"
set fsize [file size $myfile]
set fp [open $myfile r]
fconfigure $fp -translation binary
set data [read $fp $fsize]
close $fp
puts $fsize
puts [string bytelength $data]

它表明读取的字节与请求的字节不同。请求的字节与文件系统显示的相匹配;读取的实际字节数增加了22%(请求29300,得到35832)。我在Windows上使用Tcl 8.6进行了测试。

1 个答案:

答案 0 :(得分:2)

使用string length。不要使用string bytelength。它给出了“错误的”答案,或者说它回答了一个你可能不想问的问题。

更深度

string bytelength命令返回Tcl内部几乎UTF-8编码中数据的字节长度。如果你不直接使用Tcl的C API,那么你真的没有合理使用该值,而C代码实际上非常能够在没有该命令的情况下获得该值。对于ASCII文本,长度和字节长度相同,但对于具有NUL或大于U + 00007F的字符的二进制数据或文本(Unicode字符等效于ASCII DEL),值将不同。相比之下,string length命令知道如何正确处理二进制数据,并将报告您读入的字节字符串中的字节数。我们计划弃用string bytelength命令,因为它转几乎每次使用它都会成为某人代码中的错误。

(我猜测你的输入数据实际上有超出1-127范围内的6532个字节;其他字节在内部使用几乎为UTF-8的双字节表示。幸运的是,Tcl没有&#39 ; t实际上转换为该格式,直到它需要为止,而在这种情况下使用紧凑的字节数组;你通过要求string bytelength来强制它。)

背景资料

“Tcl实际使用多少内存来读取这些数据”的问题很难回答,因为Tcl会在内部对数据进行变异,以便以对您应用的操作最有效的形式保存数据。它。因为Tcl的内部类型都是完全透明的(即,他们之间的转换不会丢失信息)我们故意不讨论它们除了优化之外透视;作为程序员,你应该假装Tcl没有除了unicode字符串之外的其他类型。

您可以使用tcl::unsupported::representation命令(8.6中引入)稍微剥去面纱。 不要在代码中使用这些类型来决定做什么,因为这确实不是语言保证的东西,但它确实让你看到更多关于真实情况的内容在封面下。请记住,您看到的值与Tcl的实现所考虑的值不同。考虑你看到的价值观(没有那个魔术命令)会让你思考写作是否正确的事情。