【问题标题】:iOS : NSFileManager copyItemAtPath is memory intensiveiOS:NSFileManager copyItemAtPath 是内存密集型的
【发布时间】:2013-06-15 00:04:49
【问题描述】:

我有一个应用程序必须将一堆文件从磁盘复制到磁盘。这些文件是高清原始图像,所以它们很大。我没有怀疑 NSFileManager copyItemAtPath: 方法实际上会将内容加载到内存中以将其复制到目标路径。

我必须将此复制任务排入队列中,最多有 4 个并发操作,以避免破坏我的传输内存配额并避免崩溃,但结果是,我可能不得不等待 1 分钟才能完成所有文件的复制...

它们是一种更有效的方式来将文件从一个路径克隆到另一个路径,而无需将内容加载到内存中吗?

以下是使用仪器进行分析时发生的情况的快照:

蓝色:总生活分配

粉红色:NSFileManager copyItemAtPath:对内存的影响。

http://s9.postimg.org/io3654ty7/Screen_Shot_2013_06_18_at_12_43_03_PM.png

【问题讨论】:

    标签: ios file-io copy nsfilemanager


    【解决方案1】:

    NSFileManager copyItemAtPath:toPath:error: 和 copyItemAtURL:toURL:error: 是您可以在 iOS 中用于复制文件的最低级方法。

    所以答案是否定的。

    【讨论】:

    • NSFileManager 是一个高级类。您可以使用各种低级 C 函数来复制文件。
    • 我也尝试使用 C 调用 CopyFile() 但似乎 NSFileManager 建立在完全相同的调用之上,所以我遇到了同样的问题......
    • @user2498023 这完全取决于您如何使用 C 调用。一种方法是分块读取/写入文件。例如,您可以使用 4k 缓冲区。因此,在复制文件时,您的内存使用量在任何给定时间都不应超过数千字节。
    • @rmaddy 你的意思是我可以迭代源缓冲区并将其逐块写入它的目标路径?
    • @user2498023 是的,我说的是使用fopenreadwrite 等低级函数。
    【解决方案2】:

    与 cmets 类似,但使用 fopen、fread、fwrite,因为它们会为您处理缓冲。还有一点很重要——你应该在读写文件描述符上都设置 F_NOCACHE,否则你将大大增加专用于磁盘缓存的系统内存,如果太大可能会导致你被杀死。如果您在此处搜索文件副本和标志,您肯定会在 unix 或 C 标记项目中找到执行此操作的代码。

    【讨论】:

    • 是的,谢谢你,通过在纯 C 中实现它,我设法获得了对内存使用的更多控制。很好奇默认基础确实会自行流式传输文件:)
    • 我现在在做广告,但如果你仔细看,你可以获取底层文件描述符并在其上设置标志 - 我输入了一个 rdar 错误,说明缺少使用 Foundation 对象,但它永远不会已修复。
    猜你喜欢
    • 2015-11-22
    • 2012-07-07
    • 2012-03-05
    • 2011-01-08
    • 1970-01-01
    • 2012-04-29
    • 2015-12-12
    • 1970-01-01
    • 2011-08-12
    相关资源
    最近更新 更多