Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tcl 从二进制文件中读取错误的字节数_Tcl - Fatal编程技术网

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

Tcl 从二进制文件中读取错误的字节数,tcl,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] 它表明读取的字节与请求的字节不同。请求的字节与文件系统显示的字节匹配;实际读取

我有以下代码:

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测试了这个功能。

使用
字符串长度
。不要使用
字符串bytellength
。它给出了“错误”的答案,或者更确切地说,它回答了一个你可能不想问的问题

更深入
stringbytelength
命令返回Tcl内部几乎是UTF-8编码的数据的字节长度。如果您不直接使用Tcl的C API,那么该值实际上没有什么合理的用途,C代码实际上可以在没有该命令的情况下获得该值。对于ASCII文本,长度和字节长度相同,但对于二进制数据或NUL或大于U+00007F的字符(相当于ASCII DEL的Unicode字符)的文本,值将不同。相比之下,
string length
命令知道如何正确处理二进制数据,并将报告您读入的字节字符串中的字节数。我们计划不推荐使用
字符串bytellength
命令,因为它几乎每次都是某人代码中的一个bug

(我猜您的输入数据实际上有6532个字节,超出了1–127的范围;其他字节在内部使用几乎为UTF-8的双字节表示。幸运的是,Tcl在需要时才真正转换为该格式,而在本例中使用了紧凑的字节数组;您通过请求
字符串来强制转换ByTeleLength

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


您可以使用
tcl::unsupported::representation
命令(在8.6中引入)稍微揭开面纱.不要使用类型来决定在代码中要做什么,因为这确实不是语言所能保证的,但它确实让您看到了更多关于幕后真实情况的信息。请记住,您看到的值与Tcl实现所考虑的值不同。思考你看到的值(没有这个神奇的命令)会让你一直思考它应该写的东西。

使用
字符串长度
。不要使用
string bytellength
。它给出了“错误”的答案,或者更确切地说,它回答了一个你可能不想问的问题

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

(我猜您的输入数据实际上有6532个字节,超出了1–127的范围;其他字节在内部使用几乎为UTF-8的双字节表示。幸运的是,Tcl在需要时才真正转换为该格式,而在本例中使用了紧凑的字节数组;您通过请求
字符串来强制转换ByTeleLength

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


您可以使用
tcl::unsupported::representation
命令(在8.6中引入)稍微揭开面纱.不要使用类型来决定在代码中要做什么,因为这确实不是语言所能保证的,但它确实让您看到了更多关于幕后真实情况的信息。请记住,您看到的值与Tcl实现所考虑的值不同。思考您看到的值(没有该神奇命令)将使您不断思考编写正确的内容。

谢谢。这就解决了问题。我的下一个挑战是通过Tcl_CreateCommand将该字符串传递给C中定制的命令,而不需要解释器更改原始二进制字符串。@Eduardo由于Tcl几乎是UTF8编码,二进制数据将通过C str传递这意味着您可以使用
Tcl\u NewStringObj(theStr,-1)
将参数存储在
Tcl\u Obj*
ref中,并使用
Tcl\u GetByteArrayFromObj
访问二进制字节。它返回的
无符号字符*
指针在