我在Ruby中处理一个巨大的JSON文件时遇到了麻烦.我正在寻找的是一种逐个处理它的方法,而不会在内存中保留太多数据.
我认为yajl-ruby gem会做这项工作,但它会消耗我所有的记忆.我也看过Yajl :: FFI和JSON:流宝石,但有明确说明:
对于较大的文档,我们可以使用IO对象将其流式传输到解析器中.我们仍然需要解析对象的空间,但文档本身永远不会完全读入内存.
这是我用Yajl做的事情:
file_stream = File.open(file, "r")
json = Yajl::Parser.parse(file_stream)
json.each do |entry|
    entry.do_something
end
file_stream.close
Run Code Online (Sandbox Code Playgroud)
内存使用量持续增加,直到进程被终止.
我不明白为什么Yajl会在内存中保留已处理的条目.我可以以某种方式释放它们,还是我误解了Yajl解析器的功能?
如果无法使用Yajl完成:有没有办法在Ruby中通过任何库?
我有一个包含JSON哈希的大文件(> 50Mb).就像是:
{ 
  "obj1": {
    "key1": "val1",
    "key2": "val2"
  },
  "obj2": {
    "key1": "val1",
    "key2": "val2"
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)
我想解析散列中的每个项目,而不是解析整个文件并说出前十个元素.我实际上并不关心关键,即obj1.
如果我将上面的内容转换为:
  {
    "key1": "val1",
    "key2": "val2"
  }
  "obj2": {
    "key1": "val1",
    "key2": "val2"
  }
Run Code Online (Sandbox Code Playgroud)
我可以使用Yajl流轻松实现我想要的东西:
io = File.open(path_to_file)
count = 10
Yajl::Parser.parse(io) do |obj|
  puts "Parsed: #{obj}"
  count -= 1
  break if count == 0
end
io.close
Run Code Online (Sandbox Code Playgroud)
有没有办法在不必更改文件的情况下执行此操作?也许在Yajl中有某种回调?
我正在尝试使用yajl-py解析GitHub存档文件.我相信文件的基本格式是JSON对象流,因此文件本身不是有效的JSON,但它包含的对象.
为了测试这一点,我安装了yajl-py然后使用他们的示例解析器(来自https://github.com/pykler/yajl-py/blob/master/examples/yajl_py_example.py)来尝试解析文件:
python yajl_py_example.py < 2012-03-12-0.json
Run Code Online (Sandbox Code Playgroud)
其中2012-03-12-0.json一个已解压缩的GitHub存档文件.
看来这种事情应该来自他们在Ruby中的参考实现.Python包不处理JSON流吗?
顺便说一句,这是我得到的错误:
yajl.yajl_common.YajlError: parse error: trailing garbage
          9478bbc3","type":"PushEvent"}{"repository":{"url":"https://g
                     (right here) ------^
Run Code Online (Sandbox Code Playgroud) 我想安装 yajl-py。我尝试过这个:pip install yajl-py。但有一个错误:
OSError : Yajl shared object cannot be found . Please install Yajl and confirm it is on your shared lib path.  
Run Code Online (Sandbox Code Playgroud)
你有什么想法吗?
我有YAJL解析我所包含的示例中给出的简单元素没有问题.(字符串,整数,数组......)
示例代码可以在这里找到:http://lloyd.github.io/yajl/yajl-2.0.1/example_2parse_config_8c-example.html
但现在我有这种类型的JSON对象:
{
"cmd":2,
"properties":
    [
        {
        "idx":40,
        "val":8813.602692
        },
        {
        "idx":41,
        "val":960
        },
        {
        "idx":42,
        "val":2
        },
        {
        "idx":48,
        "val":9
        }
    ]
Run Code Online (Sandbox Code Playgroud)
}
我可以检索命令(参见链接示例中使用的变量的定义):
const char * path[] = {"cmd", (const char *) 0 };
yajl_val v = yajl_tree_get(ynode, path, yajl_t_number);
if (v)
  *cmd = (commands)((int)YAJL_GET_INTEGER(v));
Run Code Online (Sandbox Code Playgroud)
我可以使用以下命令获取属性数组的引用:
int ar_sz;
const char * path[] = {"properties", (const char *) 0 };
yajl_val v = yajl_tree_get(ynode, path, yajl_t_array);
if (v)
  {
  ar_sz = v->u.array.len;
  }
Run Code Online (Sandbox Code Playgroud)
它给了我正确的数组大小,但我不知道如何从数组元素中检索嵌套元素idx和val.
非常感谢任何帮助
Rails 2.3.6开始使用快速新的json库yajl-ruby,"如果可用的话".
在yajl-ruby自述文件的"JSON gem Compatibility API"部分中,它概述了一种方法,可以放入yajl-ruby包含并让应用程序的其余部分无缝地获取它.
所以,理想情况下,我想
实现这一目标的最简单方法是什么?我猜:
config.gem 'yajl-ruby', :lib => 'yajl/json_gem'
Run Code Online (Sandbox Code Playgroud)
作为environment.rb中的第一个宝石.这样做不会导致任何错误,但我不知道如何知道rails是否正在为自己使用它.
谢谢!约翰
我正在尝试让 YAJL 在我的应用程序中工作 - 一直在通过 Twitter API 和 Digg API 对其进行测试,但我似乎无法让它工作。
我不确定我哪里出错了。使用以下代码访问 Twitter 流 API:(删除了用户名/密码)
max_allowed_errors = 1200
consecutive_errors = 0
while consecutive_errors < max_allowed_errors do
  url = URI.parse("https://[username]:[password]!@stream.twitter.com/1/statuses/sample.json")
  begin
    Yajl::HttpStream.get(url) do |status|
      consecutive_errors = 0
     # puts status.inspect
    end
  rescue Yajl::HttpStream::InvalidContentType
    consecutive_errors += 1
  end
  sleep(0.25*consecutive_errors)
end
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
Yajl::HttpStream::HttpError in DashboardsController#streamit
Code 200 expected got 0
Run Code Online (Sandbox Code Playgroud)
错误是指这一行:
Yajl::HttpStream.get(url) do |status|
Run Code Online (Sandbox Code Playgroud)
我想避免使用特定于 API 的 gem,这样我就可以重用代码并在未来使用其他 API(即 TweetStream)。
在此先感谢您的帮助!如果您有任何问题,或者我是否可以澄清这一点,请告诉我。
哦!如果您有建议,我会注意到我愿意接受其他 gems 来管理流媒体。
我一定做错了...否则这可能是YAJL中的错误,但我对此表示高度怀疑。我无法从json对象中检索第一个元素。我回到YAJL源,使用示例parse_config.c对此进行了测试,但它也失败了。
使用sample.config
/*
 * The configuration file for Yahoo! BrowserPlus, included in the YAJL
 * tree as a sample configuration file for parsing.
 *
 * This is the configuration file for BrowserPlus
 */
{
    // The type of build this is, which is accessible to JavaScript via
    // BrowserPlus.getPlatformInfo(); 
    // Different build types should only differ in signatures accepted
    // (BrowserPlus.crt) and configured distribution servers.
    "BuildType": "ephemeral",
    // the base url for the "primary" distribution server.  This server will
    // …Run Code Online (Sandbox Code Playgroud)