Ruby序列化和持久化存储(Marshal、Pstore)操作方法详解
作者:骏马金龙 发布时间:2024-04-26 17:20:16
Ruby Marshal序列化
Marshal是Ruby的核心库,可以将一些对象以二进制的方式序列化保存到文件中,需要时再从文件中加载重新构建成对象,即反序列化。
Marshal对数值、字符串、数组、布尔值等基础数据的序列化保存没有任何问题。
但并非所有类型的数据都能序列化。Marshal从序列化文件中加载并重新构建成对象的过程中会执行一些操作,但还原的过程有些内容可能会丢失它不能序列化I0流对象以及代码类对象: Proc对象、 单例对象、匿名类和模块,这是它的限制所在。
序列化和反序列化的过程非常简单:
# 一个嵌套数组
arr = [
%w(Perl Python PHP),
%w(C C++ Java Golang),
%w(Shell Powershell Cmdline)
]
# 将arr对象序列化保存到文件中
File.open('/tmp/data.dat', "w") do |file|
Marshal.dump(arr, file)
end
# 反序列化
File.open('/tmp/data.dat') do |file|
data = Marshal.load(file)
end
p data
Marshal.dump()还可以通过第三个参数指定最多允许序列化多少个嵌套的对象层次,即深度,超出了深度将报错。其默认值为-1,此时表示不检查深度,即dump所有层次。例如:
arr = [
%w(Perl Python PHP),
[ %w(C C++), %(Java Golang) ], #=> 3层
%w(Shell Powershell Cmdline)
]
# 将arr对象序列化保存到文件中
File.open('/tmp/data.dat', "w") do |file|
Marshal.dump(arr, file, 4) #=> 小于4将报错
end
如果想要指定对象中要序列化的内容,或者指定序列化成什么类型,可以在类中编写marshal_dump
和marshal_load
方法。例如,只dump一部分数据并以数组的方式保存:
class Klass
def initialize name, age, height
@name = name
@age = age
@height = height
end
def marshal_dump
[@name, @age]
end
# 反序列化,arr是序列化时的数组
# 最终它返回一个Klass的实例对象
def marshal_load arr
@name, @age = arr
end
end
# 序列化Klass的一个对象,但只会包含name和age两个属性
obj = Klass.new("junmajinlong", 23, 170)
File.open('/tmp/me.dat','w') do |file|
Marshal.dump(obj, file)
end
# 反序列化,得到一个Klass的实例对象,并设置name和age属性
obj1 = File.open("/tmp/me.dat") do |file|
Marshal.load file
end
p obj1
#=> #<Klass:0x00007fffcc0119f8 @name="junmajinlong", @age=23>
显然,上面反序列化的过程中缺少了一个height属性。为了让对象完整,在反序列化的时候需要根据反序列化得到的结果合理构建新对象。例如,使用instance_eval()构建新对象:
def marshal_load arr
self.instance_eval do
initialize(*arr, 170)
end
end
Ruby Pstore存储
Pstore(persistence store)是Ruby的一个持久化存储的标准库,它以基于Hash数据类型的方式将数据以key-value的方式存储在文件中(二进制的),其中value是想要存储的数据,key是这部分数据的一个名称。
在Pstore中,key称为root,每个key都是一个root。
Pstore是基于事务的,所以多次增删改数据的过程是原子的,可统一提交(commit)、统一回滚(abort)。commit()和abort()时都会立即终止本次事务,所以它们后面的代码不会执行,如果没有指定commit()或abort(),则在退出transaction的时候自动保存。
因为pstore每次读都要先加载文件部分内容到内存(直到找到对应的key),所以读效率不高。再者,每次写入都需要拷贝文件的绝大部分数据,所以效率更低。因此,Pstore只适用于少量数据、少量读写的数据存储场景。
例如,持久化保存到文件:
require 'pstore'
s = PStore.new('/tmp/pstore.dat')
s.transaction do
s["p1"] = {name: "junmajinlong", age: 23, height: 170 }
s["p2"] = {name: "junma", age: 22, height: 180}
s.commit
s["p3"] = {name: "jinlong", age: 24}
end
s.transaction do
# 覆盖p2
s["p2"] = {name: "jinlong", age: 24, height: 170 }
end #=> 自动commit
从pstore文件中读取数据:
require 'pstore'
s = PStore.new("/tmp/pstore.dat")
p2 = s.transaction do
s["p2"]
end
p p2
puts p2.name
transaction(read_only=false)
还可以指定参数设置该事务是否只读,如果设置了只读,则事务内对pstore做任何修改都会抛出错误。
Pstore还有其它一些辅助方法:
[KEY] :获取元素的值,如果元素不存在则返回nil
delete() :删除元素,可指定元素不存在时的默认值参数
fetch() :获取元素,如果元素不存在,默认报错,可指定默认返回值
path() :返回pstore文件的路径
root?() :检查key是否存在
roots() :返回所有的key
来源:https://www.junmajinlong.com/ruby/ruby_marshal_pstore/
猜你喜欢
- 前言在Python中变量名规则与其他大多数高级语言一样,都是受C语言影响的,另外变量名是大小写敏感的。Python是动态类型语言,也就是说不
- Liwu_Items表,CreateTime列建立聚集索引 第一种,sqlserver2005特有的分页语法 代码如下:declare @p
- 今天重新研究了下VB里面的ScriptControl组件,发现asp里面也能调用。研究了下方法,后来和lcx讨论了下。得到了如下代码,在此感
- window.opener 的用法 window.opener 返回的是创建当前窗口的那个窗口的引用,比如点击了a.htm上的一
- 一、旧式的字符串格式化% 操作符参考以下示例:>>> name = "Eric">>>
- JS:$(".con").eq(0).show(); $(".btn span").cl
- @StartIndex为当前页起始序号,@EndIndex为当前页结束记录序号,可以直接作为参数输入,也可以通过输入PageSize和Pag
- 本文实例讲述了thinkphp的URL路由规则与配置方法。分享给大家供大家参考。具体分析如下:一、URL规则1、默认是区分大小写的2、如果我
- 从大规模数据集中寻找物品间的隐含关系被称作关联分析或关联规则学习。过程分为两步:1.提取频繁项集。2.从频繁项集中抽取出关联规则。 频繁项集
- 在写完前面“模块化”相关的文章后,感觉试图用“模块化”本身去讲什么是“模块化”真是不容易讲得清。相信大家都多多少少能理解什么是“模块化”,但
- 很多时候,由于程序设计需要,要求在asp的include包含文件里调用动态的文件。如<!--#include file=&q
- 在php中实现验证码还是很方便的,关键点在于掌握php gd库与session的用法。纵观网上php 生成验证码的例子,无不是php gd库
- 外联接。外联接可以是左向外联接、右向外联接或完整外部联接。 在 FROM 子句中指定外联接时,可以由下列几组
- tkinter提供了三个模块,可以创建弹出对话窗口:(使用必须单独导入模块)1.messagebox消息对话框示例:askokcanceli
- 在python中,文件使用十分频繁,本文将向大家介绍python文件路径的操作:得到指定文件路径、得到当前文件名、判断文件路径是否存在、获得
- 因为系统的一个Bug,导致数据库表中出现重复数据,需要做的是删除重复数据且只保留最新的一条数据。具体场景是这样的有张订单关联额外费用表,而且
- 一、插补查找算法插补查找算法又称为插值查找,它是折半查找算法的改进版。插补查找是按照数据的分布,利用公式预测键值所在的位置,快速缩小键值所在
- 1. js的数据类型1.1 js引入方式<!DOCTYPE html><html lang="en"&
- Capstone 是一个轻量级的多平台、多架构的反汇编框架,该模块支持目前所有通用操作系统,反汇编架构几乎全部支持,本篇文章将运用LyScr
- 用清理软件清理电脑垃圾的时候,发现微信存了很多图片,进入路径一看,全是以.dat为格式的文件:尝试了直接把后缀名的.dat 改 .jpg和.