iOS:用于大文件下载的 NSFileHandle 与 NSOutputStream

Posted

技术标签:

【中文标题】iOS:用于大文件下载的 NSFileHandle 与 NSOutputStream【英文标题】:iOS: NSFileHandle vs NSOutputStream for large file download 【发布时间】:2013-06-28 00:24:14 【问题描述】:

ios 上,我们的应用程序正在下载一个大约 400MB 的 zip 文件。下载文件时出现间歇性崩溃。

当前我正在使用 [NSFileHandle writeData:] 在数据进入时写入数据,并且没有存储在内存中。但我想知道操作系统是否以某种方式将其存储在内存中?

NSOutputStream 会是下载大文件的更好解决方案吗?或者可能是标准的 unix 文件描述符?

我们的文件句柄是这样设置的:

NSFileManager * fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:tmpFilePath.path contents:nil attributes:nil]; 
_zipFile = [NSFileHandle fileHandleForWritingAtPath:tmpFilePath.path];

目前我的 NSURLConnection 委托方法如下所示:

- (void) connection:(NSURLConnection *) connection didReceiveData:(NSData *) data 
   [_zipFile writeData:data];

因此,来自请求的数据不会存储或附加到任何其他数据对象。这不应该只是写入磁盘而不影响内存吗?

谢谢

【问题讨论】:

我使用NSOutputStream 正是为了这个目的,它工作正常。 (这是 Apple 在SimpleURLConnections sample 中展示的模式。)但我只是尝试了两种方式,两者在内存消耗方面似乎都相当尊重(40mb 文件,下载期间内存飙升至 3mb,但很快稳定在 1mb) .我怀疑问题必须在其他地方(僵尸或其他东西)。您如何断定NSFileHandle 是问题的根源? 你在使用僵尸吗?分配工具报告什么? 此下载是应用程序中唯一发生的事情。应用程序的其余部分取决于正在下载的这个 zip 文件,因此有一个带有进度条的视图控制器用于此下载。您会推荐我使用 Instruments 中的哪个工具来监控? 另外,通过静态分析器(“产品”菜单上的“分析”)运行您的代码,以确保您没有任何问题。 (你应该有一个干净的健康清单;如果报告了任何问题,你必须解决这些问题。)最后,你可以通过“泄漏”工具运行你的代码,以确保它没有报告任何泄漏(尽管我可以'到目前为止你提供的代码中没有任何想象)。 【参考方案1】:

我认为您使用NSFileHandle 没有任何问题。我承认我一直使用NSOutputStream,但我只是尝试了两种方式(NSFileHandleNSOutputStream),就消耗的内存而言,两者似乎都相当尊重。下载一个 40mb 的文件,在下载开始时分配量飙升至 3mb,但很快稳定在 1mb):

所以,我会通过“Allocations”和“Leaks”运行您的应用程序(如果您选择“Leaks”,您会得到两者)并查看它的外观。

如果您还没有,请通过静态分析器(“产品”菜单上的“分析”)运行您的代码,以确保您没有任何问题。 (你应该有一个干净的健康单;如果报告了任何问题,你必须解决这些问题。)我还要确保关闭僵尸(因为在跟踪所有这些释放的对象的过程中,它为每个...创建一个僵尸对象...很小,但它会消耗内存。

【讨论】:

以上是关于iOS:用于大文件下载的 NSFileHandle 与 NSOutputStream的主要内容,如果未能解决你的问题,请参考以下文章

iOS学习之文件管理器(NSFileManager)和文件对接器(NSFileHandle)

如何从 NSFileHandle * 获取 FILE *?

ios大文件下载之开始和暂停

NSFileManager&&NSFileHandle

ios开发网络学习十:利用文件句柄实现大文件下载

2016 - 1- 23 大文件下载