我有一个简单的二进制文件,其中包含彼此相邻的 32 位浮点数。
使用 Julia,我想读取每个数字(即每个 32 位字(,并将它们按顺序放入Float32
格式数组中。
通过查看文档,我尝试了一些不同的东西,但都产生了不可能的值(我正在使用具有已知值的二进制文件作为虚拟输入(。看来:
-
Julia 一次读取一个字节的二进制文件。
-
朱莉娅将每个字节放入
Uint8
数组中。
例如,readbytes(f, 4)
给出一个无符号 8 位整数的 4 元素数组。 read(f, Float32, DIM)
也给出了奇怪的价值观。
有人知道我应该如何进行吗?
我不确定直接Float32
读取它的最佳方式,但给定一个 4*n Uint8
s 的数组,我会使用 reinterpret
将其转换为 n 个 Float32
s 的数组(文档链接(:
raw = rand(Uint8, 4*10) # i.e. a vector of Uint8 aka bytes
floats = reinterpret(Float32, raw) # now a vector of 10 Float32s
带输出:
julia> raw = rand(Uint8, 4*2)
8-element Array{Uint8,1}:
0xc8
0xa3
0xac
0x12
0xcd
0xa2
0xd3
0x51
julia> floats = reinterpret(Float32, raw)
2-element Array{Float32,1}:
1.08951e-27
1.13621e11
(编辑2020:过时,请参阅最新答案。我发现了问题。以单精度浮点格式导入二进制数据的正确方法是read(f, Float32, NUM_VALS)
,其中f
是文件流,Float32
是数据类型,NUM_VALS
是二进制数据文件中的字数(值或数据点(。
事实证明,每次调用read(f, [...])
时,数据指针都会迭代到二进制文件中的下一项。
这使人们能够简单地逐行读取数据:
f = open("my_file.bin")
first_item = read(f, Float32)
second_item = read(f, Float32)
# etc ...
但是,我想在一行代码中加载所有数据。在调试时,我多次在同一文件指针上使用read()
,而没有重新声明文件指针。结果,当我尝试正确的操作(即read(f, Float32, NUM_VALS)
(时,我得到了一个意想不到的值。
自 5 年前以来,Julia 语言发生了很大变化。 read()
不再具有同时指定类型和长度的 API。 reinterpret()
创建二进制数组的视图,而不是具有所需类型的数组。现在看来最好的方法是预先分配所需的数组并用 read!
填充它:
data = Array{Float32, 1}(undef, 128)
read!(io, data)
这会用所需的浮点数填充data
。