我只是想知道该函数实际上如何存储数据。因为对我来说,它看起来完全奇怪。假设我有以下代码:
import numpy as np
filename = "test.dat"
print(filename)
fileobj = open(filename, mode='wb')
off = np.array([1, 300], dtype=np.int32)
off.tofile(fileobj)
fileobj.close()
fileobj2 = open(filename, mode='rb')
off = np.fromfile(fileobj2, dtype = np.int32)
print(off)
fileobj2.close()
现在我期望文件内有 8 个字节,其中每个元素由 4 个字节表示(并且我可以接受任何字节序)。但是,当我在十六进制编辑器中打开文件(使用带有十六进制编辑器插件的记事本++)时,我得到以下字节:
01 00 C4 AC 00
5个字节,我根本不知道它代表什么。第一个字节看起来像是数字,但接下来的内容很奇怪,肯定不是“300”。
但是重新加载会显示原始数组。
这是我在python中不明白的东西,还是在notepad++中的问题? - 我注意到如果我选择不同的“编码”,十六进制看起来会有所不同(嗯?)。另外:Windows 确实报告它的长度为 8 个字节。
您可以很容易地看出该文件实际上确实有8个字节,与您期望的相同8个字节(
01 00 00 00 2C 01 00 00
),只需使用Notepad++以外的任何东西来查看该文件,包括仅替换您的off = np.fromfile(fileobj2, dtype=np.int32)
使用 off = fileobj2.read()
然后 print
字节(这会给你 b'\x01\x00\x00\x00,\x01\x00\x00'
1))。
而且,从你的评论来看,在我建议之后,你尝试了一下,并且看到了这一点。
这意味着这要么是 Notepad++ 中的错误,要么是您使用它的方式有问题; Python、NumPy 和您自己的代码都很好。
1) 如果不清楚:
'\x2c'
和 ','
是同一个字符,并且 bytes
使用可打印 ASCII 表示形式来表示可打印 ASCII 字符,以及尽可能使用熟悉的转义符,如 '\n'
,仅对其他值使用十六进制反斜杠转义。
您期望
300
是什么样子?
写入数组,并将其以二进制形式读回(在 ipython 中):
In [478]: np.array([1,300],np.int32).tofile('test')
In [479]: with open('test','rb') as f: print(f.read())
b'\x01\x00\x00\x00,\x01\x00\x00'
有8个字节,
,
只是一个可显示的字节。
实际上,我不需要通过文件来得到这个:
In [505]: np.array([1,300]).tostring()
Out[505]: b'\x01\x00\x00\x00,\x01\x00\x00'
执行同样的操作:
[255]
b'\xff\x00\x00\x00'
[256]
b'\x00\x01\x00\x00'
[300]
b',\x01\x00\x00'
[1,255]
b'\x01\x00\x00\x00\xff\x00\x00\x00'
使用 2 的幂(以及更少的 1),很容易识别字节中的模式。
frombuffer
将字节字符串转换回数组:
In [513]: np.frombuffer(np.array([1,300]).tostring(),int)
Out[513]: array([ 1, 300])
In [514]: np.frombuffer(np.array([1,300]).data,int)
Out[514]: array([ 1, 300])
从最后一个表达式来看,
tofile
只是将数组缓冲区以字节形式写入文件。