我想将一个对象保存到文件中,然后从文件中轻松地读取它。作为一个简单的例子,假设我有以下的三维数组:
m = [[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]]
有没有一个简单的Ruby API可以让我在不编写解析器来解释文件数据的情况下实现这一点?在我提供的示例中很容易,但随着对象变得更加复杂,使对象持久化变得烦人。
我想将一个对象保存到文件中,然后从文件中轻松地读取它。作为一个简单的例子,假设我有以下的三维数组:
m = [[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]]
有没有一个简单的Ruby API可以让我在不编写解析器来解释文件数据的情况下实现这一点?在我提供的示例中很容易,但随着对象变得更加复杂,使对象持久化变得烦人。
Marshal
和 YAML
。
Marshal
和YAML
都使用dump
和load
方法进行序列化和反序列化。m = [
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
],
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
]
# Quick way of opening the file, writing it and closing it
File.open('/path/to/yaml.dump', 'w') { |f| f.write(YAML.dump(m)) }
File.open('/path/to/marshal.dump', 'wb') { |f| f.write(Marshal.dump(m)) }
# Now to read from file and de-serialize it:
YAML.load(File.read('/path/to/yaml.dump'))
Marshal.load(File.read('/path/to/marshal.dump'))
你需要注意与文件读写相关的文件大小和其他细节问题。
当然,更多信息可以在API文档中找到。
YAML和Marshal是最明显的选择,但根据您计划对数据进行的操作,sqlite3也可能是一个有用的选项。
require 'sqlite3'
m = [[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]]
db=SQLite3::Database.new("demo.out")
db.execute("create table data (x,y,z,value)")
inserter=db.prepare("insert into data (x,y,z,value) values (?,?,?,?)")
m.each_with_index do |twod,z|
twod.each_with_index do |row,y|
row.each_with_index do |val,x|
inserter.execute(x,y,z,val)
end
end
end
sqlite3
,因为它是从数据中推断类型而不是使用严格的类型系统,所以存在许多数据类型不一致的问题:https://www.sqlite.org/datatype3.html - thesmart
File.open('/path/to/file.extension', 'wb') {|f| f.write(Marsshal.dump(m)) }
和File.open('/path/to/file.extension', 'rb') {|f| m = Marshal::load(f)}
(将其设置为二进制读写,这可能是标准操作,否则会出现ASCI-8BIT到UTF8转换错误)- 如果m是手动定义类的对象,则必须确保在Marshall :: load之前加载此类(否则会出现类/模块未知错误)。 - Yo LudkeMarshal#load
之前加载类/模块是理所当然的,但你提到它是正确的。此外,这段代码是在1.8.7中编写的(也适用于1.9.3),但感谢您指出2.0.0的情况。我将尝试并更新答案。 - Swanandrequire 'yaml'
。 - Nick