使用os模块读取np.float64等多字节二进制数据异常的技术求助
解决os模块读取二进制文件中np.float64数据的问题
你的问题出在两个关键细节上:一是对os.read()的参数理解有误,二是选错了NumPy解析二进制数据的方法。咱们一步步来修正:
问题根源解析
os.read()的参数是字节数,不是元素数:你设置的total_num_to_read = n*dim是要读取的元素个数,但os.read()需要的是字节总数。每个np.float64占8字节,所以正确的字节数应该是n*dim*8(或者用np.dtype(np.float64).itemsize动态获取,适配更多数据类型)。np.fromiter()不适合解析二进制字节串:fromiter()会把字节串里的每个单独字节作为一个迭代元素处理,相当于把每个字节强行转成float64类型,这完全违背了多字节数据的解析逻辑。
正确的解决方案
用np.frombuffer()处理读取到的字节串,它能直接把连续的字节块按照指定的数据类型解析成NumPy数组,完美适配你的二进制读写场景。
修改后的完整代码
import os import numpy as np # Write n = 10 dim = 2 fd = os.open('test.dat', os.O_CREAT | os.O_WRONLY) data_w = np.random.uniform(low=0.5, high=13.3, size=(n,dim)).astype(np.float64) print("Written Data are:\n%s\n" % data_w) os.write(fd, data_w.tobytes()) os.close(fd) print("------------------ \n") # Read start_read = 0 # 可修改为任意字节偏移量,比如从第3行开始:start_read = 3 * dim * np.dtype(np.float64).itemsize num_elements_to_read = n * dim itemsize = np.dtype(np.float64).itemsize total_bytes_to_read = num_elements_to_read * itemsize fd = os.open('test.dat', os.O_RDONLY) os.lseek(fd, start_read, 0) raw_data = os.read(fd, total_bytes_to_read) # 读取正确的字节数 data_r = np.frombuffer(raw_data, dtype=np.float64).reshape(-1, dim) print("Data Read are:\n%s\n" % data_r) os.close(fd)
随机读取的扩展说明
如果之后需要从任意行开始读取,只需要计算正确的起始字节偏移量:
# 示例:从第3行开始读取5行数据 k = 3 m = 5 start_offset = k * dim * itemsize read_bytes = m * dim * itemsize os.lseek(fd, start_offset, 0) raw_data = os.read(fd, read_bytes) data_r = np.frombuffer(raw_data, dtype=np.float64).reshape(-1, dim)
这样处理后,读取的数据就会和写入的完全一致了。
内容的提问来源于stack exchange,提问作者Kristofer
相关产品推荐
相关产品推荐

