如何以良好的性能将字符串数组写入/读取到.bin

时间:2018-09-20 12:28:41

标签: julia binaryfiles

将字符串数组写入.bin格式的操作如下

out =  open("string_array.bin","w")
a = ["first string","second string","third string"]
write(out,a)
close(out)

但是当回读数组a时,事情开始变得棘手。

out =  open("string_array.bin","r")
a = read(out)
close(out)
typeof(a) # returns Array{UInt8,1}

如何将Array {UInt8,1}转换回原始类型为Array {String,1}的数组?

当字符串数组包含300+百万个元素时,它也必须工作,即解决方案必须性能良好。

2 个答案:

答案 0 :(得分:2)

以下是一些选择:

  • serialization,它的局限性在于它是为短期存储而设计的(它要求Julia的读写文件具有相同的系统映像)。
  • JLD2.jl,需要注意的是,在撰写本文时,Julia 1.0上的软件包存在一些未解决的问题(应该尽快修复-您可以检查出是否对您有影响的问题-主要是处理missing;鉴于您所写的内容,您不应受到它们的影响)
  • 最后,您可以使用旨在处理表格数据(例如CSV.jlFeather.jl)的读取器/写入器,因为您的数据可以视为单列表

答案 1 :(得分:2)

所以Bogumil是对的,这有点笨拙,但是如果您热衷于读写二进制文件,那么这里是一个用于读写Vector{String}的实现,该实现通过转换每个{{1} }到String,然后将每个Vector{UInt8}写入文件,并对每个Vector{UInt8}使用初始Int64来存储其长度。该文件还以一个额外的Vector{UInt8}开头,其中存储了Int64的长度。然后,读取例程使用此信息将其全部拉回并转换回Vector{String}

Vector{String}

我可能包含的类型信息多于必要的类型信息,但这可能会使事情变得更加明显。另外,对不起,我习惯用单缸纸做这种事情,但是如果需要,您可以轻松打开包装。这是一些测试代码(只需调整文件路径):

my_write(fid1::IOStream, x::Vector{UInt8}) = begin ; write(fid1, Int64(length(x))) ; write(fid1, x) ; end
my_write(fid1::IOStream, x::Vector{Vector{UInt8}}) = begin ; write(fid1, Int64(length(x))) ; [ my_write(fid1, y) for y in x ] ; end
my_read(fid1::IOStream, ::Type{Vector{UInt8}})::Vector{UInt8} = begin i = read(fid1, Int64) ; [ read(fid1, UInt8) for a = 1:i ] ; end
my_read(fid1::IOStream, ::Type{Vector{Vector{UInt8}}})::Vector{Vector{UInt8}} = begin i = read(fid1, Int64) ; [ my_read(fid1, Vector{UInt8}) for a = 1:i ] ; end
my_write(myfilepath::String, x::Vector{String}) = open(fid1 -> my_write(fid1, [ Vector{UInt8}(codeunits(y)) for y in x ]), myfilepath, "w")
function my_read(myfilepath::String, ::Type{Vector{String}})::Vector{String}
    x = open(fid1 -> my_read(fid1, Vector{Vector{UInt8}}), myfilepath, "r")
    return [ String(y) for y in x ]
end

请注意,通过一点努力,可以使此代码更通用,因此只要myfilepath = "/home/colin/Temp/test_file.bin" x = ["abc", "de", "f", "", "ghij"] my_write(myfilepath, x) my_read(myfilepath, Vector{String}) 是可写的,它就几乎可以用于任何Vector{Vector{T}}。实际上,如果您真的很聪明,只要可以正确执行递归,就应该可以将其推广到任何T