Как я могу сохранить объект в файл? - PullRequest
24 голосов
/ 30 ноября 2010

Я хотел бы сохранить объект в файл, а затем легко прочитать его из файла. В качестве простого примера, скажем, у меня есть следующий 3d-массив:

m = [[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]],
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]]

Существует ли простой Ruby API, который я могу использовать для достижения этой цели без программирования синтаксического анализатора для интерпретации данных из файла? В приведенном мной примере это просто, но по мере усложнения объектов становится раздражающим постоянство объектов.

Ответы [ 3 ]

51 голосов
/ 30 ноября 2010

Вам необходимо сериализовать объекты, прежде чем вы сможете сохранить их в файл и десериализовать их, чтобы получить их обратно. Как отметил Кори, широко используются 2 стандартные библиотеки сериализации: 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.

15 голосов
/ 30 ноября 2010
3 голосов
/ 30 ноября 2010

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
...