繁体   English   中英

iOS / iPhone日记/文件系统缓存

[英]iOS / iPhone Journaling / File System Caching

从本地设备测试中,我已经看到将文件写入iOS文件系统(无论您使用的调用级别如何)通常会在文件完全提交到闪存之前返回成功。 意思是,如果你硬重置设备然后重启,你的文件可以回滚(如果写完成或原子)或损坏。 这种延迟的来源是什么(文档很受欢迎,我找不到任何东西),有没有办法在实际的文件系统写入完成时获得反馈。 例如,我想承认从远程服务器接收和存储一段数据,但我发现在写“报告”成功后确认它可能会导致硬件崩溃或电源故障时数据丢失。

由于这是一个4年前的问题,我不仅会提供答案,还会提供我在搜索时所采用的路径。

我无法在官方文档中找到任何明确的解释: 文件系统编程指南 性能提示”部分中只有一条线索。 它指出:

应用程序可以使用F_NOCACHE标志调用BSD fcntl函数来启用或禁用文件的缓存。 有关此函数的更多信息,请参阅fcntl。

启用F_NOCACHE标志并不能解决您所说的问题,但是, fcntl方法的手册指出了一个您可能感兴趣的选项:

F_FULLFSYNC与fsync(2)相同的事情然后要求驱动器将所有缓冲的数据刷新到永久存储设备

(来自man fcntl ,见这里 )。

我已经查看了fsync的手册以获取更多详细信息。 它最终给了我关于问题和解决方案的最清晰,最容易理解的解释:

请注意,虽然fsync()会将所有数据从主机刷新到驱动器(即“永久存储设备”),但驱动器本身可能无法将数据物理地写入盘片很长一段时间,并且可能会写出来有序序列。

具体来说,如果驱动器断电或操作系统崩溃,应用程序可能会发现只写了一些或没有写入数据。 磁盘驱动器还可以重新排序数据,以便可以存在以后的写入,而较早的写入则不存在。

这不是理论上的边缘情况。 使用实际工作负载和驱动器电源故障可轻松复制此方案。

对于需要更严格保证其数据完整性的应用程序,Mac OS X提供F_FULLFSYNC fcntl。 F_FULLFSYNC fcntl要求驱动器将所有缓冲的数据刷新到永久存储器。 需要严格写入顺序的应用程序(如数据库)应使用F_FULLFSYNC来确保其数据按预期顺序写入。

(来自man fsync ,请看这里 )。

是的,这绝对不是理论上的边缘情况。 值得庆幸的是,一旦你知道这个问题,解决方案是微不足道的:

let filePath: String = "your file path"

// you can use other option than read-write
let fd = open(String(path.utf8), O_RDWR)

// if fd is -1, there was an error opening file, handle it as you wish
guard fd != -1 else { return }

// syncResult is -1 if sync operation failed, handle it as you wish
let syncResult = fcntl(fd, F_FULLFSYNC)

// don't forget to close opened file
close(fd)

fcntl完成后,您的数据将被保存。

请注意,此操作比通常写入文件(通过NSFileManagerwriteToURL方法系列) writeToURL 如果出现性能问题,最好将写入移至后台线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM