我有一堆大的JSON文件(> 500MB),我想用ruby脚本解析(我正在尝试用YAJL gem解析)。
我注意到JSON文件存在格式错误,因此所有文件均由“多个” JSON对象组成,而没有适当的树状结构或数组。在下面,您可以找到JSON文件的外观:
testfile.json:
{title: "Don Quixote", author: "Miguel de Cervantes", printyear: 2010}
{title: "Great Gatsby", author: "F. Scott Fitzgerald", printyear: 2014}
{title: "Ulysses", author: "James Joyce", printyear: 2010}
这是解析文件的脚本:
require 'yajl'
json = File.new('testfile.json', 'r')
hash = Yajl::Parser.parse(json)
这是我收到的错误消息:
Yajl::ParseError: Found multiple JSON objects in the stream but no block or the on_parse_complete callback was assigned to handle them.
如果您能指导我如何解决此问题,我将不胜感激。
答案 0 :(得分:3)
您收到的错误消息(“在流中发现了多个JSON对象……” )表示您的输入包含多个但有效的JSON对象,因此我假设您的实际文件看起来像这样:
{"title":"Don Quixote","author":"Miguel de Cervantes","printyear":2010}
{"title":"Great Gatsby","author":"F. Scott Fitzgerald","printyear":2014}
{"title":"Ulysses","author":"James Joyce","printyear":2010}
YAJL的功能之一是:
在流或字符串之间连续解析和编码多个 JSON对象。
因此,根据上面的输入(作为文件或字符串),您可以将 block 传递到parse
,每个解析的对象都将调用它:
require 'yajl'
io = File.open('testfile.json')
Yajl::Parser.parse(io) do |book|
puts "“#{book['title']}” by #{book['author']} (#{book['printyear']})"
end
输出:
“Don Quixote” by Miguel de Cervantes (2010)
“Great Gatsby” by F. Scott Fitzgerald (2014)
“Ulysses” by James Joyce (2010)
答案 1 :(得分:0)
请勿使用JSON.parse
,因为文件的内容不是JSON。该文件中的每一行看起来都像一个Ruby哈希,因此可以使用不同的解析方法。
您应该可以使用YAML.load(line)
来解析每一行。
此外,因为文件很大,所以请勿将整个文件加载到内存中。使用File.foreach
逐行加载。
require 'yaml'
lines = []
File.foreach('testfile.json') do |line|
lines << YAML.load(line)
end