将字符串数组写入.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+百万个元素时,它也必须工作,即解决方案必须性能良好。
答案 0 :(得分:2)
以下是一些选择:
missing
;鉴于您所写的内容,您不应受到它们的影响)答案 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
。