Ruby 如何将对象保存到文件中?

Ruby 如何将对象保存到文件中?,ruby,json,serialization,marshalling,yaml,Ruby,Json,Serialization,Marshalling,Yaml,我想将一个对象保存到一个文件中,然后轻松地从文件中读取它。作为一个简单的示例,假设我有以下3d阵列: m = [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]] 是否有一个简单的RubyAPI,我可以使用它来实现这一点,而无需编程解析器来解释文件中的数据?在我给出的示例中,这很简单,但随着对象变得更加复杂,使对象持久化变得很烦人。请参见封送: -或- YAML:在将对象保存到文件并反序列化以检索它

我想将一个对象保存到一个文件中,然后轻松地从文件中读取它。作为一个简单的示例,假设我有以下3d阵列:

m = [[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]],
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]]
是否有一个简单的RubyAPI,我可以使用它来实现这一点,而无需编程解析器来解释文件中的数据?在我给出的示例中,这很简单,但随着对象变得更加复杂,使对象持久化变得很烦人。

请参见封送:

-或-


YAML:

在将对象保存到文件并反序列化以检索它们之前,您需要序列化这些对象。正如Cory所提到的,2个标准序列化库被广泛使用,并且

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是最明显的答案,但根据您计划对数据执行的操作,可能也是一个有用的选项

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

没有足够的权限编辑您的答案并将其添加到其中。:-)@实际上,对于我来说,在Ruby 2.0.0中,这不起作用,应该是
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工作之前加载该类(否则会出现类/模未知错误)@YoLudke-我认为在
封送#load
之前加载类/模块是给定的,但您明确提到它是正确的。此外,该代码是在1.8.7中编写的(也适用于1.9.3),但感谢您指出关于2.0.0的内容。我将试一试并更新答案。封送不是一个好的持久性工具,格式取决于Ruby版本,无法在新的Rubies中解码旧的封送格式。@muistoshort同意。封送不是一个好的持久性工具,格式取决于Ruby版本,而且没有其他方法s无法在新Rubies中解码旧的封送处理格式..我不建议,sqlite3有许多数据类型不一致,因为它从数据推断类型,而不是使用严格的类型系统: