【问题标题】:Altering and updating a JSON file更改和更新 JSON 文件
【发布时间】:2017-05-26 19:43:22
【问题描述】:

我编写了一个小脚本,它循环我当前的 Jsonfile,但无法附加键和值。

这是我的文件

[
  {
    "URL": "https://p59-caldav.icloud.com",
  }
]

我想像这样附加一个键和值

[
  {
    "URL": "https://p59-caldav.icloud.com",
    "test": "test"
  }
]

我当前的脚本设置

#!/usr/bin/env ruby

require 'rubygems'
require 'json'
require 'domainatrix'

jsonHash = File.read("/Users/ReffasCode/Desktop/sampleData.json")
array = JSON.parse(jsonHash)

File.open("/Users/BilalReffas/Desktop/sampleData.json","w") do |f|

  array.each do |child|
    url = Domainatrix.parse(child["URL"])
    json = {
      "url" => child["URL"],
      "provider" => url.domain,
      "service" => url.subdomain,
      "context" =>  url.path,
      "suffix" => url.public_suffix
    }

    f.write(JSON.pretty_generate(json))
  end
end

脚本覆盖了我的整个 jsonfile...这不是我想要的:/

【问题讨论】:

  • 您确实需要在此处修复缩进,因为我认为您对循环内部的内容和不存在的内容感到困惑。
  • 您必须覆盖原件。您无法轻松安全地追加、插入或修改磁盘上的 JSON(或一般的文本文件)。

标签: json ruby


【解决方案1】:

这是未经测试的,但看起来很正确:

ORIGINAL_JSON = 'sampleData.json'
NEW_JSON = ORIGINAL_JSON + '.new'
OLD_JSON = ORIGINAL_JSON + '.old'

json = JSON.parse(File.read(ORIGINAL_JSON))

ary = json.map do |child|
  url = Domainatrix.parse(child['URL'])
  {
    'url' => child['URL'],
    'provider' => url.domain,
    'service' => url.subdomain,
    'context' => url.path,
    'suffix' => url.public_suffix
  }
end

File.write(NEW_JSON, ary.to_json)

File.rename(ORIGINAL_JSON, OLD_JSON)
File.rename(NEW_JSON, ORIGINAL_JSON)
File.delete(OLD_JSON)

重要的是在所有处理完成之前不要覆盖原始文件,因此写入新文件,关闭新文件和旧文件,然后将旧文件重命名为安全的名称,将新文件重命名为原始名称,然后能够删除原件。如果您不遵循这样的流程,那么如果代码或机器在中途崩溃,您将面临损坏或丢失原始数据的风险。

有关详细信息,请参阅“How to search file text for a pattern and replace it with a given value”。

【讨论】:

  • File.mv 不存在你需要使用 FileUtils.mv 并且需要'fileutils'
  • 或者,使用 File 的版本。
【解决方案2】:

使用f.write 的最简单方法可能是用它来替换文件的全部内容。考虑到这一点,让我们看看我们是否可以在内存中将文件的全部内容组合成我们想要的内容,然后再写入。

#!/usr/bin/env ruby

require 'rubygems'
require 'json'
require 'domainatrix'

write_array = []
jsonHash = File.read("/Users/ReffasCode/Desktop/sampleData.json")
read_array = JSON.parse(jsonHash)
read_array.each do |child|
    url = Domainatrix.parse(child["URL"])
    write_array << {
        "url" => child["URL"],
        "provider" => url.domain,
        "service" => url.subdomain,
        "context" =>  url.path,
        "suffix" => url.public_suffix
    }
end

File.open("/Users/BilalReffas/Desktop/sampleData.json","w") do |f|
    f.write(JSON.pretty_generate(write_array))
end

注意一些变化:

  1. 固定缩进:)
  2. 删除了一些嵌套
  3. 使用文件的全部内容写入一次。除非您有一个非常大的文件或非常需要流水线 I/O,否则这可能是最简单的做法。

【讨论】:

  • 最后一段写成File.write("/Users/BilalReffas/Desktop/sampleData.json", JSON.pretty_generate(write_array))更方便。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多