在Ruby中如何将对象数组写入文件且读取时恢复原有实例状态
解决方案
之前尝试失败的原因
- 尝试1失败原因:
pp方法输出的是调试用的可读文本,不是标准JSON格式,且JSON默认仅支持字符串、数值、数组、哈希等基础类型,无法直接序列化嵌套的自定义类实例,因此JSON解析会直接报错。 - 尝试2失败原因:
Marshal.dump生成的是二进制序列化内容,你用默认的文本写入模式w打开文件时,Ruby会尝试将二进制内容转换为当前环境的文本编码,触发编码转换错误。
推荐实现方案
方案1:使用Marshal(还原度最高、性能最好)
Marshal是Ruby内置的序列化工具,可以完整还原任意Ruby对象的结构,包括嵌套的自定义类实例,不需要额外修改类定义,是该需求的最优选择,只需要把文件读写改为二进制模式即可:
保存代码:
serialized_array = Marshal.dump(myArray) # 用二进制写入模式wb打开文件 File.open('./myArray.dat', 'wb') { |f| f.write(serialized_array) }
读取代码:
# 用二进制读取模式rb打开文件 serialized_array = File.open('./myArray.dat', 'rb').read myArray = Marshal.load(serialized_array)
注意:Marshal序列化的内容存在Ruby版本兼容性,建议相同大版本的Ruby环境下读写,如果需要跨版本兼容可以选择方案2。
方案2:使用YAML序列化(兼容性更好、文本可读)
如果需要序列化结果为可读的文本格式,或者需要跨Ruby版本使用,可以用内置的YAML库,它也支持自定义类实例的序列化:
保存代码:
require 'yaml' File.write('./myArray.yml', myArray.to_yaml)
读取代码:
require 'yaml' # 3.1+版本Ruby需要显式声明允许反序列化的自定义类,低版本可省略permitted_classes参数 myArray = YAML.load_file('./myArray.yml', permitted_classes: [你用到的自定义类名1, 自定义类名2, ...])
注意:Ruby 3.1+版本YAML默认开启安全加载,需要在permitted_classes里列出所有要反序列化的自定义类,避免反序列化注入风险。
内容的提问来源于stack exchange,提问作者Leero11
相关产品推荐
相关产品推荐

