<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Ruby的標準庫YAML基於Psych:https://ruby-doc.org/stdlib-2.6.2/libdoc/psych/rdoc/Psych.html
require 'yaml'
之後,為大多數的基本資料型別都提供了 to_ yaml()
方法,用於將各資料型別的物件轉換為yaml格式。
例如:
require 'yaml' require 'set' p "hello world".to_yaml p 123.to_yaml p %w(perl shell php).to_yaml p ({one: 1, two: 2}).to_yaml p Set.new([1,2,3]).to_yaml
得到:
"--- hello worldn" "--- 123n" "---n- perln- shelln- phpn" "---n:one: 1n:two: 2n" "--- !ruby/object:Setnhash:n 1: truen 2: truen 3: truen"
也可以使用YAML.dump()
方法實現和to_yaml相同的功能,它還可以寫入檔案。
users = [{name: 'Bob', permissions: ['Read']}, {name: 'Alice', permissions:['Read', 'Write']}] File.open("/tmp/a.yml","w") { |f| YAML.dump(users, f) }
檢視檔案:
--- - :name: Bob #=> 注意,保留了hash源資料中的符號 :permissions: - Read - :name: Alice :permissions: - Read - Write
用YAML.load()從YAML中讀取資料:
require 'yaml' pp YAML.load(DATA) __END__ mysql: passwd: P@ssword1! user: root port: 3306 other1: nil other2: false other3: "" hosts: - ip: 10.10.1.1 hostname: node1 - ip: 10.10.1.2 hostname: node2
得到:
{"mysql"=> {"passwd"=>"P@ssword1!", #=> 注意,key是String而非Symbol "user"=>"root", "port"=>3306, "other1"=>"nil", "other2"=>false, "other3"=>"", "hosts"=> [{"ip"=>"10.10.1.1", "hostname"=>"node1"}, {"ip"=>"10.10.1.2", "hostname"=>"node2"}]}}
如果想讓hash的key是符號而非字串,可以設定選項symbolize_names: true
:
pp YAML.load(DATA, symbolize_names: true)
需要注意,YAML可以將物件進行序列化,所以有幾方面注意事項:
require 'set'
則無法還原物件使用JSON.generate()可以將物件或陣列轉換為JSON格式的資料:
require 'json' p JSON.generate "abc" p JSON.generate 123 p JSON.generate true p JSON.generate nil p JSON.generate [2,3,4] p JSON.generate({name: "junmajinlong", age: 23}) require 'set' p JSON.generate(Set.new([1,23,44]))
得到:
""abc"" "123" "true" "null" "[2,3,4]" "{"name":"junmajinlong","age":23}" ""#<Set: {1, 23, 44}>""
當require 'json'
後,很多ruby型別都具備了一個to_json的方法,可以直接將該型別的資料轉換為json資料:
p ({name: "junmajinlong", age: 23}).to_json p (Set.new([1,23,44])).to_json
得到:
"{"name":"junmajinlong","age":23}" ""#<Set: {1, 23, 44}>""
此外,JSON.dump()也可以將物件轉換為JSON格式的字串,而且它還支援寫入檔案:
hsh = {name: "junmajinlong", age: 23} File.open("/tmp/a.json", "w") {|f| JSON.dump(hsh, f)}
要從json格式字串轉為ruby物件,有一些選項可設定,參考https://ruby-doc.org/stdlib-2.7.1/libdoc/json/rdoc/JSON.html,比如*symbolize_names*
選項表示是否將json object中的key解析為符號型別的key,如果設定為false,則解析為字串的key。
要將json格式的字串解析為Ruby資料型別(Hash),使用JSON.parse()
,
require 'json' hsh = '{"name": "junmajinlong", "age": 23}' p JSON.parse(hsh) p JSON.parse(hsh, symbolize_names: true)
注意,上面的json字串必須是合理的json資料,比如key必須使用雙引號包圍而不能使用單引號,字串必須使用雙引號包圍,等等。比如"{'name': 'junmajinlong', 'age': 23}"
就不是合理的json字串。
要從json檔案中讀取json資料並轉換為Ruby資料,使用load():
data = File.open("/tmp/a.json") do |f| JSON.load(f) end pp data #=> {"name"=>"junmajinlong", "age"=>23}
json支援的資料型別有:
從一種語言的資料轉換為Json資料時,如果資料型別也是JSON所支援的,可直接轉換,但如果包含了JSON不支援的型別,則可能報錯,也可能以一種物件字串的方式儲存,這取決於對應的實現。
可以在物件中定義as_json
實體方法來決定物件如何轉換為json字串,再定義類方法from_json()
來決定如何從json字串中恢復為一個物件。
例如,
require 'json' require 'date' class Person attr_accessor :name, :birthday def initialize name, birthday @name = name @birthday = DateTime.parse(birthday) end end File.open("/tmp/p.json", "w") do |f| JSON.dump(Person.new("junmajinlong", "1999-10-11"), f) end
檢視儲存的json資料:
$ cat /tmp/p.json "#<Person:0x00007fffc7e575d0>"
定義as_json
和frmo_json
:
require 'json' require 'date' class Person attr_accessor :name, :birthday def initialize name, birthday @name = name @birthday = DateTime.parse(birthday) end def as_json { name: @name, birthday: @birthday.strftime("%F") } end def self.from_json json data = JSON.parse(json) new(data["name"], data["birthday"]) end end
之後要序列化、反序列化該物件,可:
data = Person.new("junmajinlong", "1999-10-11").as_json p data p1=Person.from_json(JSON.dump data) p p1.birthday
如果是讀寫json檔案,可:
person1 = Person.new("junmajinlong", "1999-10-11") File.open("/tmp/p.json", "w") do |f| JSON.dump(person1.as_json, f) end p1 = File.open("/tmp/p.json") do |f| Person.from_json(f.read) # Person.from_json(JSON.load(f).to_json) end p p1
測試了json標準庫、oj和fast_josnparser解析json的效能,測試項包括:
注:
測試的json字串數量大約50M。
測試了ruby 2.7.1和ruby 3.0.1兩個版本,gem包的版本資訊如下:
fast_jsonparser (0.5.0) json (default: 2.5.1) oj (3.11.7)
測試程式碼:
require 'benchmark' require 'json' require 'oj' require 'fast_jsonparser' # warm json_file='test' # 檔案大小大約50M str = File.read(json_file) ######## JSON puts " load file ".center(80, '-') Benchmark.bm(30) do |x| x.report("JSON.load:") { File.open(json_file){ |f| JSON.load(f) } } x.report("Oj.load_file:") { Oj.load_file(json_file) } x.report("FastJsonparser.load:") { FastJsonparser.load(json_file) } end puts puts " load file with symbolize_keys ".center(80, '-') Benchmark.bm(30) do |x| x.report("JSON.load:") { File.open(json_file){ |f| JSON.load(f, nil, symbolize_names: true, create_additions: false) } } x.report("Oj.load_file:") { Oj.load_file(json_file, symbol_keys: true) } x.report("FastJsonparser.load:") { FastJsonparser.load(json_file, symbolize_keys: true) } end puts puts " parse str ".center(80, '-') Benchmark.bm(30) do |x| x.report("JSON.parse:") { JSON.parse(str) } x.report("Oj.load:") { Oj.load(str) } x.report("FastJsonparser.parse:") { FastJsonparser.parse(str) } end puts puts " parse str with symbolize_keys ".center(80, '-') Benchmark.bm(30) do |x| x.report("JSON.parse:") { JSON.parse(str, symbolize_names: true) } x.report("Oj.load:") { Oj.load(str, symbol_keys: true) } x.report("FastJsonparser.parse:") { FastJsonparser.parse(str, symbolize_keys: true) } end obj = JSON.parse(str, symbolize_names: true) puts puts " dump JSON to str ".center(80, '-') Benchmark.bm(30) do |x| x.report("JSON.dump:") { JSON.dump(obj) } x.report("Oj.dump:") { Oj.dump(obj) } end puts puts " dump JSON to file ".center(80, '-') Benchmark.bm(30) do |x| x.report("JSON.dump:") { File.open('0_json_dump', 'w') {|f| JSON.dump(obj, f) } } x.report("Oj.to_file:") { Oj.to_file('0_oj_dump', obj) } end
測試結果:
Ruby 2.7.1中:
---------------------------------- load file ----------------------------------- user system total real JSON.load: 1.591831 0.058021 1.649852 ( 1.738119) Oj.load_file: 1.350385 0.057684 1.408069 ( 2.434268) <-慢 FastJsonparser.load: 0.653968 0.103258 0.757226 ( 0.848913) <-快 ------------------------ load file with symbolize_keys ------------------------- user system total real JSON.load: 1.212617 0.039052 1.251669 ( 1.349545) Oj.load_file: 1.432059 0.098950 1.531009 ( 2.679610) <-慢 FastJsonparser.load: 0.695538 0.008384 0.703922 ( 0.797081) <-快 ---------------------------------- parse str ----------------------------------- user system total real JSON.parse: 1.343596 0.000000 1.343596 ( 1.350368) Oj.load: 1.133612 0.000000 1.133612 ( 1.140939) FastJsonparser.parse: 0.701701 0.012340 0.714041 ( 0.720296) <-快 ------------------------ parse str with symbolize_keys ------------------------- user system total real JSON.parse: 1.250775 0.000000 1.250775 ( 1.258796) Oj.load: 1.131296 0.000000 1.131296 ( 1.138020) FastJsonparser.parse: 0.697433 0.015962 0.713395 ( 0.719439) <-快 ------------------------------- dump JSON to str ------------------------------- user system total real JSON.dump: 1.374611 0.028454 1.403065 ( 1.403081) Oj.dump: 1.025049 0.040184 1.065233 ( 1.065246) <-快 ------------------------------ dump JSON to file ------------------------------- user system total real JSON.dump: 1.234362 0.040246 1.274608 ( 1.369214) Oj.to_file: 1.168707 0.000000 1.168707 ( 1.270957)
Ruby 3.0.1中:
---------------------------------- load file ----------------------------------- user system total real JSON.load: 1.362151 0.083610 1.445761 ( 1.569754) Oj.load_file: 1.343601 0.182046 1.525647 ( 2.684472) <-慢 FastJsonparser.load: 2.634435 0.052734 2.687169 ( 2.776105) <-慢 ------------------------ load file with symbolize_keys ------------------------- user system total real JSON.load: 1.287954 0.018572 1.306526 ( 1.409770) Oj.load_file: 1.478750 0.043847 1.522597 ( 2.668882) <-慢 FastJsonparser.load: 2.717857 0.006164 2.724021 ( 2.822728) <-慢 ---------------------------------- parse str ----------------------------------- user system total real JSON.parse: 1.242225 0.008661 1.250886 ( 1.304554) Oj.load: 1.097922 0.000000 1.097922 ( 1.110031) FastJsonparser.parse: 2.602679 0.017232 2.619911 ( 2.634604) <-慢 ------------------------ parse str with symbolize_keys ------------------------- user system total real JSON.parse: 1.368262 0.000000 1.368262 ( 1.380730) Oj.load: 1.332349 0.000000 1.332349 ( 1.346331) FastJsonparser.parse: 2.706804 0.007238 2.714042 ( 2.726935) <-慢 ------------------------------- dump JSON to str ------------------------------- user system total real JSON.dump: 1.724653 0.009250 1.733903 ( 1.733912) Oj.dump: 1.298235 0.030041 1.328276 ( 1.328279) <-快 ------------------------------ dump JSON to file ------------------------------- user system total real JSON.dump: 1.765664 0.040595 1.806259 ( 1.905785) Oj.to_file: 1.228744 0.020309 1.249053 ( 1.349684) <-快 =end
效能測試結論:
即:
dump: Oj.dump > JSON.dump ruby3 之前: FastJsonparser.load > JSON.load > Oj.load_file FastJsonparser.parse > Oj.load > JSON.parse ruby3 之後: JSON.load > Oj.load_file > FastJsonparser.load Oj.load > JSON.parse > FastJsonparser.parse
有一個名為multi_json的gem包,它提供多種json包的功能,預設採用OJ作為json的適配引擎。它支援下面幾種json介面卡:
如果oj已被require,則預設採用oj處理json,如果oj沒有被require,而是require了yajl,則採用yajl處理json,依次類推。
它提供了load()和dump()方法:
load(json_str, options = {}) options: symbolize_keys: true, false adapter: oj, json_gem, yajl, json_pure, ok_json dump(object, options = {})
更多關於Ruby處理操作YAML和Ruby處理操作json方法請檢視下面的相關連結
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45