iPad – 分析一个非常巨大的JSON – 文件(50和100 MB之间)

我试图parsing一个非常大的JSON文件在iPad上。 文件大小在50到100 MB之间(有一个初始文件,每个月会有一个新的全套数据,这些数据将被下载,parsing并保存到coredata中)

我正在为企业构build这个应用程序作为企业解决scheme–JSON文件包含敏感的客户数据,它需要保存在本地ipad,所以它将工作,即使离线。 当文件低于20MB时,它工作,但现在数据集变大了,我真的需要parsing它。 我在parsing过程中收到内存警告,并在第三次警告后,它只是崩溃。 我有几个不同的核心数据实体,我只是设置来自json文件(当应用程序第一次启动时)的所有值,并在所有事情完成后,我正在做[context save]

我希望有人能给我一些关于如何处理这些大文件的build议。 我正在考虑将json文件拆分成几个较小的json文件,并可能在多个线程中parsing它们,但是我不知道这是否是正确的方法。 我想一个大问题是整个文件被保存在内存中 – 也许有某种方式将它“stream”到内存或类似的东西?

我正在使用JSONKit( https://github.com/johnezang/JSONKit )parsing文件,因为我已经读过它是最快的一个(也许有一个更慢的内存更容易?)。

提前致谢。

1)将数据写入文件,然后使用NSData的dataWithContentsOfFile:options:error:并指定NSDataReadingMappedAlwaysNSDataReadingUncached标志。 这将告诉系统使用mmap()来减less内存占用量,而不是使用内存块(这会使速度变慢,但对iOS的负担更小)给文件系统caching带来负担。

2)您可以使用YAJL SAX风格的JSONparsing器来解码对象。

注:我没有做过2),而是使用了1)中体现的技术。

3)我自己最终需要这样一个东西,写了SAX-JSON-Parser-ForStreamingData ,可以绑定到任何asynchronous下载器(包括我自己的)。

鉴于移动设备上当前的内存限制,很可能无法parsing100 MB的JSON文本,然后创build一个Foundation对象的表示forms ,这个对象本身的内存大小要比源JSON文本的大小大10倍。

也就是说,为了分配基础对象所需的空间,您的JSON结果需要大约1 GB RAM。

因此,无论如何获取和读取和parsinginput,都可能无法创build一个巨大的JSON表示。 你需要把它分成许多小的。 不过,这可能需要在服务器端进行修改。

另一个解决scheme是这个,但更详细的说明:

使用一个SAX风格的parsing器,它通过stream式API将巨大的JSON作为input,并输出几个较小的JSON文本(内部部分)。 SAX样式parsing器可以使用Blocks API(dispatch lib)将结果 – 较小的JSONasynchronous传递给另一个JSONparsing器。 也就是说,较小的JSON会被提供一个通常的JSONparsing器,它会产生JSON表示,而这些JSON表示又会被反馈给您的CoreData Model Generator。

您甚至可以下载巨大的JSON并与SAX样式parsing器同时parsing,同时创build更小的JSON并同时将其存储到Core Data中。

您需要的是具有SAX风格API的JSONparsing器,它可以parsinginput文本的块,快速执行,并可以创buildFoundation对象的表示forms。

我知道只有一个JSON库有这个function集,甚至有一些例子可以部分显示你可以如何完成这个:JPJson on GitHub。 parsing器也非常快 – 在ARM上它比JSONKit快。 注意:它的实现是用C ++编写的,需要几个步骤才能在开发者机器上安装它。 它有一个良好的文档Objective-C API,但。

想补充一点,我是作者;)更新很快就可以实现,它利用了最新的C ++ 11编译器和C ++ 11库特性,从而实现了更快的代码(ARM比JSONKit快25%,两倍作为NSJSONSerialization)。

给你同样的速度的事实:parsing器能够下载(通过WiFi)和parsing包括1000个JSON(每个25千字节)的25 MByte数据在WiFi 802.11g的7秒内,在WiFi 802.11n 4秒,包括在iPad 2上创build和释放1000个表示。