如果关闭文件,iOS 上是否仍然需要 FileHandle.synchronize()?

Is a FileHandle.synchronize() still necessary on iOS if closing the file?

提问人:oxygen 提问时间:3/24/2023 最后编辑:oxygen 更新时间:3/26/2023 访问量:174

问:

在 Windows 和 Linux 系统上,意外断电可能会导致最近写入的文件被垃圾字节或空字节损坏(在 Hyper-V VM 中运行时很常见,否则 .vhdx 会与物理存储对齐并一直刷新;在物理磁盘上不太常见,但也在那里;例如,在 Windows 上的 VMware 上经常发生 .vmdks 损坏, 尤其是数据库文件)。

一些关键的 Linux 服务会为设置文件创建许多备份。就像 iSCSI 目标 (LIO) 管理库 rtslib 一样,它为 /etc/target/saveconfig.json 创建了 10 个备份(如果有人快速连续编辑 11 次,不确定这是否有帮助)。

虽然 iOS 设备在电池几乎耗尽时会完全关机,但仍有可能发生意外断电的情况:例如冰冻温度导致电池突然意外损失过多安培数(在寒风中,铝制 iPhone 在使用时甚至空闲时会很快死机)

我也有类似的情况,特定的设置文件在 iOS 应用程序中至关重要。

在 Swift iOS 上是否也可以立即刷新到磁盘?FileHandle.close()Data.write(options: .atomic)

如果是这样,原子写入是否刷新?是在重命名之前还是之后?

我应该避免吗?String.data.write()

在 iOS 上(在 String.data.write 之后)是否仍然需要确保缓存的数据已写入存储?FileHandle.synchronize()

完成后,打开同一文件的文件句柄并调用是否会导致之前写入的数据同步?还是已经同步了?String.data.write()FileHandle.synchronize()

iOS Swift 刷新 文件句柄

评论

0赞 oxygen 3/24/2023
需要明确的是,我知道关闭文件句柄会删除 .synchronize() 的可用性。这不是问题所在。
0赞 oxygen 3/25/2023
我在 GitHub 上的 Swift 源代码中偶然发现的各种文档注释(我目前在 iPad 上)也没有表明任何类型的脏缓冲区同步。以老式的方式做事,直到事情变得更清楚。

答:

0赞 gnasher729 3/25/2023 #1

atomic的意思是atomic。文件要么已写入,要么没有更改。

我不知道它是否完美,但我相信你能做的任何事情都不会更好。首先,他们将数据写入未命名的文件。这就是停电最有可能打击你的地方。但是还没有目录条目,所以最坏的情况是你会丢失数据。然后,在文件系统之外进行目录更改。

因此,现在他们只需要一次原子写入即可将所有更改链接到文件系统中。你总是想要这样,你不想要半写的块。因此,在开始实际写入之前(在启动驱动器、移动到正确的轨道并等待块之后)进行硬件检查电源输入,您只需要足够的电源即可完成物理写入。

评论:“sync”将尽最大努力确保所有软件写入调用最终都出现在磁盘上。如果在“同步”之前断电,这显然会失败。如果写入头开始第一次写入和完成最后一次写入之间存在断电,则会严重失败。这取决于硬件:有一段时间你会失去电源输入,而稍后会因为电源不足而导致写入失败,可能是在写入过程中。这不是立竿见影的。因此,如果您检测到电源线拔下(无电源输入)并且在这种情况下没有开始第一次写入,如果电源在此后一纳秒消失,硬件仍然需要能够完成所有写入。

原子写入将自行进行同步。

评论

0赞 oxygen 3/25/2023
嗨,感谢您的回复,但是它没有回答问题,因为您没有触及主题,即物理写入的缓存,这是通过临时文件进行原子写入通常不会触及的一层。为您重新表述问题:“执行原子写入时,特定文件的文件系统缓存是否刷新/同步到物理存储?
0赞 oxygen 3/25/2023
The power cut timing for my question is way after the entire atomic operation is over and the application thinks all is well. If the file system cache was not flushed to physical storage before a power cut occurs (the atomic operation has finished “long ago”) then the file will likely contain garbage or could even be missing from the master file table or whatever that’s called on iOS file systems.
0赞 oxygen 3/25/2023
You can learn more about this in the iOS manual for the sync command: developer.apple.com/library/archive/documentation/System/…
0赞 oxygen 3/25/2023
From the docs: “ As information in the cache is lost after a system crash a sync() call is issued frequently by the user process update(8) (about every 30 seconds).”
0赞 oxygen 3/25/2023 #2

我在 GitHub 上的 Swift 源代码中偶然发现的各种文档注释(我目前在 iPad 上)也没有表明任何类型的脏缓冲区同步。以老式的方式做事,直到事情变得更清楚。

Perhaps a .synchronize option for the .write() function is something we’re gonna get in the future.