最后,情况似乎更加清楚。
这是《 Intel
Fortran编译器用户和参考指南》,请参阅“ 记录类型:可变长度记录”部分 。
对于记录长度大于2,147,483,639字节的记录,将其分为子记录。子记录的长度可以在1到2,147,483,639(含)之间。
前导长度字段的符号位指示记录是否继续。尾随长度字段的符号位指示先前子记录的存在。符号位的位置由文件的字节序格式决定。
连续的子记录的前导长度字段的符号位值为1。组成记录的最后一个子记录的前导长度字段的符号位值为0。具有前一个子记录的子记录的结尾长度为尾随长度。字段的符号位值为1。组成记录的第一个子记录的尾随长度字段的符号位值为0。如果符号位的值为1,则记录的长度以
二进制 形式存储 -补码 。
经过多篇文章,我意识到我被 二进制补码表示 误导了,记录标记只是按照上面的规则更改了符号,而当符号位为1时改成了 二进制补码
。无论如何,我的数据是使用不同的编译器创建的。
下面是解决方案。
数据大于2GB,因此分为几个子记录。如我们所见,第一个记录的开始标记是-2147483639,所以第一个记录的长度是2147483639,这恰好是子记录的最大长度,而不是我想的2147483640或2147483638的-2147483639的
二进制补码 。
如果我们跳过2147483639字节以读取记录结束标记,则会得到2147483639,因为它是结束标记为正的第一个子记录。
下面是检查记录标记的代码:
fp = open(file_path, "rb")while 1: prefix, = struct.unpack( '>i', fp.read(4) ) fp.seek(abs(prefix), 1) #or read |prefix| bytes data as you want suffix, = struct.unpack( '>i', fp.read(4) ) print prefix, suffix if abs(suffix) - abs(prefix): print "suffix != prefix!" break if prefix > 0: break
和丝网印刷
-2147483639 2147483639-2147483639 -214748363918 -18
我们可以看到记录的开始标记和结束标记除符号外始终相同。这三个记录的长度为2147483639、2147483639,为18个字节,不必是4的倍数。因此,第一个记录以某个整数的前3个字节结束,第二个记录以其余的1个字节开始。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)