Wil*_*iam 6 file-io binaryfiles binary-data julia
我有一个简单的二进制文件,包含彼此相邻的32位浮点数.
使用Julia,我想读取每个数字(即每个32位字)并将它们按顺序放入Float32
格式数组中.
我通过查看文档尝试了一些不同的东西,但都产生了不可能的值(我使用的是具有已知值的二进制文件作为虚拟输入).看起来:
Julia一次只读取一个字节的二进制文件.
Julia将每个字节放入一个Uint8
数组中.
例如,readbytes(f, 4)
给出一个4元素的无符号8位整数数组.read(f, Float32, DIM)
也给出了奇怪的价值.
任何人都知道我该怎么办?
我不确定Float32
直接读取它的最佳方式,但是给定一个4*n Uint8
s 的数组,我会Float32
使用reinterpret
(doc link)将其转换为n s 数组:
raw = rand(Uint8, 4*10) # i.e. a vector of Uint8 aka bytes
floats = reinterpret(Float32, raw) # now a vector of 10 Float32s
Run Code Online (Sandbox Code Playgroud)
随着输出:
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
Run Code Online (Sandbox Code Playgroud)
我发现了这个问题.以单精度浮点格式导入二进制数据的正确方法是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 ...
Run Code Online (Sandbox Code Playgroud)
但是,我想在一行代码中加载所有数据.在调试时,我曾read()
多次使用相同的文件指针而不重新声明文件指针.结果,当我尝试正确的操作时read(f, Float32, NUM_VALS)
,我得到了一个意想不到的值.
自 5 年前以来,Julia 语言发生了很大变化。read()
不再有 API 同时指定类型和长度。reinterpret()
创建二进制数组的视图,而不是具有所需类型的数组。看来现在最好的方法是预先分配所需的数组并用以下内容填充它read!
:
data = Array{Float32, 1}(undef, 128)
read!(io, data)
Run Code Online (Sandbox Code Playgroud)
这填充data
了所需的浮点数。