iOS:下载、解包、解码和解析大文件
我正在开发的一个项目(iPhone/Obj-C)要求我获取一个大文件(通过 HTTP Post)并处理它。服务器将返回一些 XML 包装 BASE64 编码的 gzip 压缩的 XML 数据。即:服务器-> XML-> BASE64-> GZIP-> XML->我的模型
数据量会有所不同,但我被告知最终的 XML 将约为 5 MB。
我想在数据到达时对其进行解包、解码和解析。
我正在寻找提示/指示。 (理想情况下,那里有现有的已发布代码,但我在搜索中没有看到“流友好”示例。)
我最终会子类化 NSStream 吗?
理想的解决方案适用于运行 iOS 3.2 及更高版本的设备。
谢谢!
A project I'm working on (iPhone/Obj-C) requires me to fetch a large file (via HTTP Post) and process it. The server will return some XML wrapping BASE64 encoded gzipped XML data. ie: SERVER -> XML -> BASE64 -> GZIP -> XML -> My Model
The amount of data will vary, but I'm told the final XML will be about 5 MB.
I'd like to unwrap, decode, and parse the data as it arrives.
I'm looking for tips / pointers. (Ideally, there's existing published code out there, but I didn't see "stream friendly" examples in my searching.)
Will I end up subclassing NSStream?
The ideal solution will work for devices running iOS 3.2 and later.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
让服务器(Apache?)在 HTTP 中执行 gzip,iOS NSURLConnection 将在运行过程中解压缩。 HTTP 可以包含二进制数据,因此也不需要 Base64。您应该能够让 XML 作为 NSData 到达您的 NSURLConnection,您可以将其输入 SAX 类型解析器(可以在下载时进行解析)。
如果您的服务器在您的控制之下,并且该服务器仅由 iOS 应用程序使用,并且性能是您主要关心的问题,您可以尝试发送编码为二进制 plist 的模型数据。不过,XML 或 JSON 可能会更容易使用。
Have the server (Apache?) do the gzip within the HTTP, and the iOS NSURLConnection will un-gzip as it goes. HTTP can contain binary data, so Base64 is not needed either. You should be able to get XML to arrive at your NSURLConnection as NSData, which you could feed into a SAX type parser (which can parse as it downloads).
If your server is under your control, and the server is only being used by an iOS app, and performance is your main concern, you could attempt to send your model data encoded as a binary plist. XML or JSON is probably going to be easier to work with though.
好吧,这不是我提出的问题的答案,但也许是一个“解决方案”。
我正在下载的数据非常适合内存,因此没有迫切需要优化数据以将其作为流处理。
我使用出色的 ASIHTTPRequest 库 (Ben Copsey) 来获取初始 XML 并运行它通过 NSXML 解析器来获取标签。我强烈推荐 ASI-HTTP-REQUEST 给任何在 iOS 上使用 HTTP 协议的人。
接下来我使用了稍微调整(以消除 clang 警告)版本的 Matt Gallagher 的 Base64 类别 将 Base64 解包为 gzip。
然后我通过 ASI 的解码器运行 gzip 数据:
NSData* xmlData = [ASIDataDecompressor uncompressData:gzippedData error:&error];
以获取应该一直发送的 XML。< /p>最后,我通过另一个 NSXMLParser 运行 XML 以挑选出我需要的数据位。
在该项目的另一部分中,我实际上被指示获取包含数百个微小 .txt 文件的 ZIP 存档。 (是的,就是这样的工作。) 解码 ZIP 文件;我目前正在使用 Karl Moskowski 的 ZipKit。
我希望数据永远不会增长到我需要将其全部作为流处理的程度。如果确实如此,我知道一个简单的方法可以减少 33%。 :)
Well, this is not the answer to the question I asked, but perhaps a "solution".
The data I'm downloading is fitting nicely in memory, so there is no pressing need to optimize things to process as a stream.
I use the fantastic ASIHTTPRequest library (Ben Copsey) to fetch the initial XML and just run it through an NSXML parser to grab the tag. I highly recommend ASI-HTTP-REQUEST for anyone using the HTTP protocol for iOS.
Next I used a slightly tweaked (to rid clang warnings) version of Matt Gallagher' Base64 category to unwrap the Base64 to gzip.
Then I run the gzip data through ASI's decoder:
NSData* xmlData = [ASIDataDecompressor uncompressData:gzippedData error:&error];
to get at the XML that should have been sent all along.Finally, I run the XML through another NSXMLParser to pick out the bits of data I need.
In another part of the project, I'm actually directed to fetch a ZIP archive containing a few hundred tiny .txt files. (Yeah, it's that kind of gig.) To decode the ZIP file; I'm currently using ZipKit by Karl Moskowski.
I hope the data never grows to the point where I'll need to process it all as a stream. If it does, I know an easy way to shave off 33%. :)