解析大型 JSON 文件 [重复]

Posted

技术标签:

【中文标题】解析大型 JSON 文件 [重复]【英文标题】:Parse large JSON file [duplicate] 【发布时间】:2013-02-28 16:36:46 【问题描述】:

我正在编写一个访问 API、接收 JSON 文件(大量对象)并将其存储在本地的 cron 脚本。完成后,另一个脚本需要解析下载的 JSON 文件并将每个对象插入 mysql 数据库。

我目前正在使用file_get_contents()json_decode()。这将在尝试处理之前尝试将整个文件读入内存。这很好,除了我的 JSON 文件通常在 250MB-1GB+ 范围内。我知道我可以增加我的 php 内存限制,但这似乎不是我心目中最好的答案。我知道我可以运行 fopen()fgets() 来逐行读取文件,但我需要按每个 json 对象读取文件。

有没有办法读取每个对象的文件,还是有其他类似的方法?

【问题讨论】:

这个post 可以帮助你... 为什么 JSON 文件这么大? 好悲痛!来自 API 调用的 1gig 响应?这太疯狂了。开发人员是否从未听说过分页的概念。 不使用现有的json_decode 函数,逐行阅读并自己解析似乎是您唯一的选择。可能有 3rd 方库,例如 this one (从未使用过,不能说任何关于它的内容,只是一个快速的谷歌找到了它)。 如果 json 文件是数据库转储,应该有另一种解决方法.. 【参考方案1】:

这实际上取决于 json 文件包含的内容。

如果无法将文件一次性打开到内存中,那么您唯一的其他选择就是 fopen/fgets。

可以逐行读取,如果这些json对象有一致的结构,你可以很容易地检测出文件中的json对象什么时候开始,什么时候结束。

一旦你收集了一个完整的对象,你就将它插入到一个数据库中,然后继续下一个。

没有更多内容。检测 json 对象的开头和结尾的算法可能会变得复杂,具体取决于您的数据源,但我之前使用更复杂的结构 (xml) 做过类似的事情,并且效果很好。

【讨论】:

结构非常基本,1 个大型对象数组,每个对象具有相同的 3 个属性。我假设我会做一个 fgets() ,解析那个单独的字符串以找到其中的所有 JSON 对象并将它们插入到数据库中。然后我会将指针重置为最后一个成功找到的 JSON 对象的末尾并重复。你是这么想的吗? 没错。由于文件的大小差异很大(200mb 到 1gb 等),因此最好采用一种不管文件大小都可以工作的方法。【参考方案2】:

最佳解决方案:

使用某种分隔符(分页、时间戳、对象 ID 等),允许您在多个请求中以较小的块读取数据。此解决方案假定您对这些 JSON 文件的生成方式有某种控制。我的假设基于:

这很好,除了 my JSON 文件通常会 范围从 250MB-1GB+。

读取和处理 1GB 的 JSON 数据简直是荒谬的。绝对需要更好的方法。

【讨论】:

【参考方案3】:

试试这个库https://github.com/shevron/ext-jsonreader

PHP 自带的现有 ext/json 非常方便, 易于使用 - 但在处理大型项目时效率低下 大量 JSON 数据,因为它需要读取整个 JSON 数据 到内存中(例如使用 file_get_contents()),然后将其转换 一次进入一个 PHP 变量 - 对于大型数据集,这会占用很多 的记忆。

JSONReader 专为提高内存效率而设计 - 它适用于流和 可以从任何 PHP 流中读取 JSON 数据而无需加载整个 数据进入内存。它还允许开发人员提取特定的 来自 JSON 流的值,无需解码并将所有数据加载到 记忆。

【讨论】:

以上是关于解析大型 JSON 文件 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

统一解析json文件[重复]

解析csv文件中的json字符串[重复]

下载 JSON 文件,但解析显示不可读的字符 [重复]

将大型嵌套字典转储到 JSON 对象中[重复]

在 Swift 中使用动态键解析 JSON [重复]

如何通过D3.js中的JSON文件解析按键对对象进行排序[重复]