【问题标题】:Can we store multiple objects in file?我们可以在文件中存储多个对象吗?
【发布时间】:2015-02-23 03:12:55
【问题描述】:

我已经熟悉How can I save an object to a file?

但是如果我们必须将多个对象(比如哈希)存储到一个文件中。

我尝试将YAML.dump(hash) 附加到代码中不同位置的文件中。但困难的部分是读回来。由于 yaml 转储可以扩展到多行,我是否必须解析文件?此外,这只会使代码复杂化。有没有更好的方法来实现这一目标?

PS:Marshal.dump 仍然存在同样的问题。所以我更喜欢YAML,因为它更易于阅读。

【问题讨论】:

    标签: ruby yaml


    【解决方案1】:

    YAML.dump 创建单个 Yaml document。如果您在一个文件中有多个 Yaml 文档,那么您有一个 Yaml stream。因此,当您将多次调用的结果附加到YAML.dump 时,您将拥有一个流。

    如果您尝试使用YAML.load 阅读此内容,您将只能获得第一个文档。要取回所有文档,您可以使用 YAML.load_stream,它会为您提供一个数组,其中包含每个文档的条目。

    一个例子:

    f = File.open('data.yml', 'w')
    
    YAML.dump({:foo => 'bar'}, f)
    
    YAML.dump({:baz => 'qux'}, f)
    
    f.close
    

    data.yml 之后将如下所示,包含两个单独的文档:

    ---
    :foo: bar
    ---
    :baz: qux
    

    您现在可以像这样读回它:

    all_docs = YAML.load_stream(File.open('data.yml'))
    

    这会给你一个像[{:foo=>"bar"}, {:baz=>"qux"}]这样的数组。

    如果您不想一次性将所有文档加载到一个数组中,您可以将一个块传递给load_stream,并在每个文档被解析时对其进行处理:

    YAML.load_stream(File.open('data.yml')) do |doc|
      # handle the doc here
    end
    

    【讨论】:

    • 这太棒了!!我从来不知道load_stream 存在。非常感谢! :)
    【解决方案2】:

    您可以通过创建分隔符来保存多个对象(用于标记一个对象已完成并且您转到下一个对象的标记)。然后,您可以分两步处理该文件:

    • 读取文件,将其拆分为每个分隔符
    • 使用 YAML 从每个块中恢复哈希

    现在,这会有点麻烦,因为有一个更简单的解决方案。假设您要保存三个哈希:

    student = { first_name: "John"}
    restaurant = { location: "21 Jump Street" }
    order = { main_dish: "Happy Meal" }
    

    您可以简单地将它们放在一个数组中,然后转储它们:

    objects = [student, restaurant, order]
    dump = YAML.dump(objects)
    

    您可以轻松地恢复您的对象:

    saved_objects = YAML.load(dump)
    saved_student = saved_objects[0]
    

    根据您的对象关系,您可能更喜欢使用哈希而不是数组来保存它们(这样您就可以命名它们而不是根据顺序)。

    【讨论】:

    • 谢谢。在我的情况下,将它们转储到单个数组中是不可能的,所以我猜想使用分隔符并相应地解析文件,块明智是唯一的选择。我试图完全避免的事情.. :-/
    • 您能否详细说明“无法在单个数组中转储”?我很好奇,因为我也不喜欢“分隔符”解决方案
    • 好吧,我正在从单个线程中执行的不同文件中收集ObjectSpace。因此,为了使用数组,我需要在线程开始时定义它,使其成为全局并在最后转储。但问题是,这个数组的大小可能会呈指数级增长,从而影响我的结果。
    • 使用散列数组或散列散列将多个散列存储在单个文件中更为合适和标准。如果您需要可被多个线程访问的持久性,请考虑使用真正的数据库。甚至 SQLite 也可以。
    猜你喜欢
    • 1970-01-01
    • 2021-06-03
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    相关资源
    最近更新 更多