人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

Ruby解析處理YAML和json格式數(shù)據(jù)

發(fā)布日期:2022-07-15 19:17 | 文章來(lái)源:站長(zhǎng)之家

Ruby處理YAML

Ruby的標(biāo)準(zhǔn)庫(kù)YAML基于Psych:https://ruby-doc.org/stdlib-2.6.2/libdoc/psych/rdoc/Psych.html

require 'yaml' 之后,為大多數(shù)的基本數(shù)據(jù)類(lèi)型都提供了 to_ yaml() 方法,用于將各數(shù)據(jù)類(lèi)型的對(duì)象轉(zhuǎn)換為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 world\n"
"--- 123\n"
"---\n- perl\n- shell\n- php\n"
"---\n:one: 1\n:two: 2\n"
"--- !ruby/object:Set\nhash:\n  1: true\n  2: true\n  3: true\n"

也可以使用YAML.dump()方法實(shí)現(xiàn)和to_yaml相同的功能,它還可以寫(xiě)入文件。

users = [{name: 'Bob', permissions: ['Read']},
 {name: 'Alice', permissions:['Read', 'Write']}]
File.open("/tmp/a.yml","w") { |f| YAML.dump(users, f) }

查看文件:

---
- :name: Bob #=> 注意,保留了hash源數(shù)據(jù)中的符號(hào)
  :permissions:
  - Read
- :name: Alice
  :permissions:
  - Read
  - Write

用YAML.load()從YAML中讀取數(shù)據(jù):

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是符號(hào)而非字符串,可以設(shè)置選項(xiàng)symbolize_names: true

pp YAML.load(DATA, symbolize_names: true)

需要注意,YAML可以將對(duì)象進(jìn)行序列化,所以有幾方面注意事項(xiàng):

  • 在反序列化的時(shí)候需要也require涉及到的文件,例如對(duì)Set類(lèi)型序列化后,在反序列化時(shí)如不require 'set'則無(wú)法還原對(duì)象
  • 有些底層對(duì)象不能序列化,包括IO流、Ruby代碼對(duì)象Proc、Binding等
  • 不要反序列化不被信任的數(shù)據(jù)對(duì)象(比如用戶輸入的數(shù)據(jù)),此時(shí)可使用safe_load(),它默認(rèn)只允許加載以下幾種類(lèi)型的數(shù)據(jù):
    • TrueClass
    • FalseClass
    • NilClass
    • Numeric
    • String
    • Array
    • Hash
  • 如果確實(shí)想要加載額外的數(shù)據(jù)類(lèi)型,可以在safe_load()中指定參數(shù)permitted_classes: []或permitted_symbols: []

Ruby處理Json數(shù)據(jù)

轉(zhuǎn)為json格式字符串

使用JSON.generate()可以將對(duì)象或數(shù)組轉(zhuǎn)換為JSON格式的數(shù)據(jù):

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}>\""

當(dāng)require 'json'后,很多ruby類(lèi)型都具備了一個(gè)to_json的方法,可以直接將該類(lèi)型的數(shù)據(jù)轉(zhuǎn)換為json數(shù)據(jù):

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()也可以將對(duì)象轉(zhuǎn)換為JSON格式的字符串,而且它還支持寫(xiě)入文件:

hsh = {name: "junmajinlong", age: 23}
File.open("/tmp/a.json", "w") {|f| JSON.dump(hsh, f)}

json格式字符串轉(zhuǎn)為Ruby對(duì)象

要從json格式字符串轉(zhuǎn)為ruby對(duì)象,有一些選項(xiàng)可設(shè)置,參考https://ruby-doc.org/stdlib-2.7.1/libdoc/json/rdoc/JSON.html#method-i-parse,比如*symbolize_names*選項(xiàng)表示是否將jsonobject中的key解析為符號(hào)類(lèi)型的key,如果設(shè)置為false,則解析為字符串的key。

要將json格式的字符串解析為Ruby數(shù)據(jù)類(lèi)型(Hash),使用JSON.parse(),

require 'json'
hsh = '{"name": "junmajinlong", "age": 23}'
p JSON.parse(hsh)
p JSON.parse(hsh, symbolize_names: true)

注意,上面的json字符串必須是合理的json數(shù)據(jù),比如key必須使用雙引號(hào)包圍而不能使用單引號(hào),字符串必須使用雙引號(hào)包圍,等等。比如"{'name': 'junmajinlong', 'age': 23}"就不是合理的json字符串。

要從json文件中讀取json數(shù)據(jù)并轉(zhuǎn)換為Ruby數(shù)據(jù),使用load():

data = File.open("/tmp/a.json") do |f|
  JSON.load(f)
end
pp data
#=> {"name"=>"junmajinlong", "age"=>23}

自定義對(duì)象的轉(zhuǎn)換方式

json支持的數(shù)據(jù)類(lèi)型有:

  • 字符串
  • 數(shù)值
  • 對(duì)象
  • 數(shù)組
  • 布爾
  • Null

從一種語(yǔ)言的數(shù)據(jù)轉(zhuǎn)換為Json數(shù)據(jù)時(shí),如果數(shù)據(jù)類(lèi)型也是JSON所支持的,可直接轉(zhuǎn)換,但如果包含了JSON不支持的類(lèi)型,則可能報(bào)錯(cuò),也可能以一種對(duì)象字符串的方式保存,這取決于對(duì)應(yīng)的實(shí)現(xiàn)。

可以在對(duì)象中定義as_json實(shí)例方法來(lái)決定對(duì)象如何轉(zhuǎn)換為json字符串,再定義類(lèi)方法from_json()來(lái)決定如何從json字符串中恢復(fù)為一個(gè)對(duì)象。

例如,

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數(shù)據(jù):

$ cat /tmp/p.json
"#<Person:0x00007fffc7e575d0>"

定義as_jsonfrmo_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

之后要序列化、反序列化該對(duì)象,可:

data = Person.new("junmajinlong", "1999-10-11").as_json
p data
p1=Person.from_json(JSON.dump data)
p p1.birthday

如果是讀寫(xiě)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解析工具的性能測(cè)試

測(cè)試了json標(biāo)準(zhǔn)庫(kù)、oj和fast_josnparser解析json的性能,測(cè)試項(xiàng)包括:

  • 從文件中加載并解析json字符串為ruby對(duì)象
  • 從內(nèi)存json字符串中解析json字符串為ruby對(duì)象
  • 帶有symbolize_keys/symbolize_names轉(zhuǎn)換時(shí)的解析
  • json標(biāo)準(zhǔn)庫(kù)和oj將ruby對(duì)象dump為json字符串
  • json標(biāo)準(zhǔn)庫(kù)和oj將ruby對(duì)象dump為json字符串保存到文件

注:

  • fast_jsonparser沒(méi)有dump功能,只有解析json字符串功能
  • oj在將對(duì)象轉(zhuǎn)換為json字符串時(shí),可能會(huì)丟失數(shù)據(jù)的精度,比如浮點(diǎn)數(shù)的精度

測(cè)試的json字符串?dāng)?shù)量大約50M。

測(cè)試了ruby 2.7.1和ruby 3.0.1兩個(gè)版本,gem包的版本信息如下:

fast_jsonparser (0.5.0)
json (default: 2.5.1)
oj (3.11.7)

測(cè)試代碼:

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

測(cè)試結(jié)果:

Ruby 2.7.1中:

---------------------------------- load file -----------------------------------
user  systemtotal  real
JSON.load:  1.5918310.0580211.649852 (  1.738119)
Oj.load_file:  1.3503850.0576841.408069 (  2.434268) <-慢
FastJsonparser.load: 0.6539680.1032580.757226 (  0.848913) <-快
------------------------ load file with symbolize_keys -------------------------
user  systemtotal  real
JSON.load:  1.2126170.0390521.251669 (  1.349545)
Oj.load_file:  1.4320590.0989501.531009 (  2.679610) <-慢
FastJsonparser.load: 0.6955380.0083840.703922 (  0.797081) <-快
---------------------------------- parse str -----------------------------------
user  systemtotal  real
JSON.parse: 1.3435960.0000001.343596 (  1.350368)
Oj.load: 1.1336120.0000001.133612 (  1.140939)
FastJsonparser.parse:0.7017010.0123400.714041 (  0.720296) <-快
------------------------ parse str with symbolize_keys -------------------------
user  systemtotal  real
JSON.parse: 1.2507750.0000001.250775 (  1.258796)
Oj.load: 1.1312960.0000001.131296 (  1.138020)
FastJsonparser.parse:0.6974330.0159620.713395 (  0.719439) <-快
------------------------------- dump JSON to str -------------------------------
user  systemtotal  real
JSON.dump:  1.3746110.0284541.403065 (  1.403081)
Oj.dump: 1.0250490.0401841.065233 (  1.065246) <-快
------------------------------ dump JSON to file -------------------------------
user  systemtotal  real
JSON.dump:  1.2343620.0402461.274608 (  1.369214)
Oj.to_file: 1.1687070.0000001.168707 (  1.270957)

Ruby 3.0.1中:

---------------------------------- load file -----------------------------------
user  systemtotal  real
JSON.load:  1.3621510.0836101.445761 (  1.569754)
Oj.load_file:  1.3436010.1820461.525647 (  2.684472) <-慢
FastJsonparser.load: 2.6344350.0527342.687169 (  2.776105) <-慢
------------------------ load file with symbolize_keys -------------------------
user  systemtotal  real
JSON.load:  1.2879540.0185721.306526 (  1.409770)
Oj.load_file:  1.4787500.0438471.522597 (  2.668882) <-慢
FastJsonparser.load: 2.7178570.0061642.724021 (  2.822728) <-慢
---------------------------------- parse str -----------------------------------
user  systemtotal  real
JSON.parse: 1.2422250.0086611.250886 (  1.304554)
Oj.load: 1.0979220.0000001.097922 (  1.110031)
FastJsonparser.parse:2.6026790.0172322.619911 (  2.634604) <-慢
------------------------ parse str with symbolize_keys -------------------------
user  systemtotal  real
JSON.parse: 1.3682620.0000001.368262 (  1.380730)
Oj.load: 1.3323490.0000001.332349 (  1.346331)
FastJsonparser.parse:2.7068040.0072382.714042 (  2.726935) <-慢
------------------------------- dump JSON to str -------------------------------
user  systemtotal  real
JSON.dump:  1.7246530.0092501.733903 (  1.733912)
Oj.dump: 1.2982350.0300411.328276 (  1.328279) <-快
------------------------------ dump JSON to file -------------------------------
user  systemtotal  real
JSON.dump:  1.7656640.0405951.806259 (  1.905785)
Oj.to_file: 1.2287440.0203091.249053 (  1.349684) <-快
=end

性能測(cè)試結(jié)論:

  • (1).ruby 3之前,fast_jsonparser非???,但是Ruby 3中的fast_jsonparser很慢
  • (2).OJ解析本地json字符串的性能比標(biāo)準(zhǔn)庫(kù)json性能稍好,但oj從文件中加載并解析json的速度很慢
  • (3).OJ將ruby對(duì)象解析為json字符串的效率比json標(biāo)準(zhǔn)庫(kù)性能好

即:

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

有一個(gè)名為multi_json的gem包,它提供多種json包的功能,默認(rèn)采用OJ作為json的適配引擎。它支持下面幾種json適配器:

  • OjOptimized JSON by Peter Ohler
  • YajlYet Another JSON Library by Brian Lopez
  • JSONThe default JSON gem with C-extensions (ships with Ruby 1.9+)
  • JSON PureA Ruby variant of the JSON gem
  • NSJSONSerializationWrapper for Apple’s NSJSONSerialization in the Cocoa Framework (MacRuby only)
  • gson.rbA Ruby wrapper for google-gson library (JRuby only)
  • JrJacksonJRuby wrapper for Jackson (JRuby only)
  • OkJsonA simple, vendorable JSON parser

如果oj已被require,則默認(rèn)采用oj處理json,如果oj沒(méi)有被require,而是require了yajl,則采用yajl處理json,依次類(lèi)推。

它提供了load()和dump()方法:

load(json_str, options = {})
  options: 
 symbolize_keys: true, false
 adapter:  oj, json_gem, yajl, json_pure, ok_json
dump(object, options = {})

更多關(guān)于Ruby處理操作YAMLRuby處理操作json方法請(qǐng)查看下面的相關(guān)鏈接

香港服務(wù)器租用

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專(zhuān)屬顧問(wèn)服務(wù)

1對(duì)1客戶咨詢顧問(wèn)

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部