更新
我已经解决并删除了令人分心的错误.请阅读整篇文章,如果仍有问题,请随时留言.
背景
我试图使用Swift 2.0,GCD和完成处理程序在iOS上将相对较大的文件(视频)写入磁盘.我想知道是否有更有效的方法来执行此任务.在使用完成逻辑的同时,需要在不阻塞主UI的情况下完成任务,并确保尽可能快地执行操作.我有自定义对象与NSData属性,所以我目前正在尝试使用NSData上的扩展.作为示例,替代解决方案可能包括使用NSFilehandle或NSStreams以及某种形式的线程安全行为,这导致比基于当前解决方案的NSData writeToURL函数快得多的吞吐量.
NSData有什么问题吗?
请注意以下从NSData类参考(保存数据)中进行的讨论.我确实对我的临时目录执行写操作,但是我遇到问题的主要原因是我在处理大文件时可以看到UI明显滞后.这种滞后恰恰是因为NSData不是异步的(Apple Docs注意到原子写入会导致"大"文件的性能问题〜> 1mb).因此,在处理大型文件时,无论NSData方法中的内部机制是什么,都可以使用.
我做了一些挖掘,并从Apple发现了这个信息..."这个方法非常适合将数据:// URL转换为NSData对象,也可以用于同步读取短文件.如果你需要读取可能很大的文件,使用inputStreamWithURL:打开一个流,然后一次读取一个文件." (NSData类参考,Objective-C,+ dataWithContentsOfURL).这个信息似乎暗示我可以尝试使用流将文件写在后台线程上,如果将writeToURL移动到后台线程(由@jtbandes建议)是不够的.
NSData类及其子类提供了快速轻松地将其内容保存到磁盘的方法.为了最大限度地降低数据丢失的风险,这些方法提供了以原子方式保存数据的选项.原子写保证数据可以完整保存,也可以完全失败.原子写入从将数据写入临时文件开始.如果此写入成功,则该方法将临时文件移动到其最终位置.
虽然原子写操作可以最大限度地降低因文件损坏或部分写入而导致数据丢失的风险,但在写入临时目录,用户主目录或其他可公开访问的目录时,它们可能不合适.每次使用可公开访问的文件时,都应将该文件视为不受信任且可能存在危险的资源.攻击者可能会破坏或破坏这些文件.攻击者还可以使用硬链接或符号链接替换文件,从而导致写入操作覆盖或损坏其他系统资源.
在可公开访问的目录中工作时,避免使用writeToURL:atomically:方法(以及相关方法).而是使用现有文件描述符初始化NSFileHandle对象,并使用NSFileHandle方法安全地写入文件.
其他替代品
一个物品在objc.io上并发编程提供了有趣的选择"高级:文件I/O在后台".一些选项也涉及使用InputStream.Apple还有一些旧的参考文件,用于异步读取和写入文件.我发布这个问题是为了期待Swift的替代方案.
适当答案的示例
以下是可能满足此类问题的适当答案的示例.(用于流编程指南,写入输出流)
使用NSOutputStream实例写入输出流需要几个步骤:
我正在寻找最熟练的算法,适用于使用Swift,API或甚至C/ObjC将极大文件写入iOS就足够了.我可以将算法转换为适当的Swift兼容结构.
Nota Bene
我理解下面的信息错误.它包含完整性.这个问题是询问是否有更好的算法用于将大文件写入具有保证依赖序列的磁盘(例如NSOperation依赖).如果有请提供足够的信息(描述/样本为我重建相关的Swift 2.0兼容代码).如果我遗漏任何有助于回答问题的信息,请告知我们.
关于扩展名的说明
我已经在基本writeToURL中添加了一个完成处理程序,以确保不会发生意外的资源共享.我使用该文件的依赖任务永远不会面临竞争条件.
extension NSData {
func writeToURL(named:String, completion: (result: Bool, url:NSURL?) -> Void) {
let filePath = NSTemporaryDirectory() + named
//var success:Bool = false
let tmpURL = NSURL( fileURLWithPath: filePath )
weak var …Run Code Online (Sandbox Code Playgroud)