5

AFAIK,OS X 是 BSD 派生,它没有实际的强制文件锁定。如果是这样,即使我正在编写文件,我似乎也无法阻止其他程序的写入访问。

在这样的环境下如何保证文件的完整性?我的程序退出后我不在乎完整性,因为现在这是用户的责任。但至少,我认为在我的程序运行时我需要某种保证。

其他程序如何在没有强制锁定的情况下保证文件内容的完整性?尤其是数据库程序。如果有常用的技术或推荐的做法,请告诉我。

更新

我正在为非工程师用户的 GUI 应用程序的数据层寻找这个。目前,我的程序有这种情况。

  • 数据太大,无法放入 RAM。甚至很难被暂时复制。所以它不能被原子读/写,并且应该在程序运行时直接从磁盘使用。

  • 非工程师人员使用的长期运行的专业 GUI 内容编辑器应用程序。虽然用户不是工程师,但他们仍然可以使用 Finder 或其他程序同时访问文件。因此用户可以不小心删除或写入当前使用的文件。问题是用户不了解实际发生的情况,并期望程序至少在程序运行时处理文件完整性。

  • 我认为在当前情况下保证文件完整性的唯一方法是,

    1. 使用系统范围的排他强制锁打开文件。现在该文件是程序的责任。
    2. 检查完整性。
    3. 在程序运行时将文件用作外部存储器。
    4. 写下所有的修改。
    5. 开锁。现在该文件是用户的责任。

    因为 OS X 缺少系统范围的强制锁定,所以现在我不知道该怎么做。但我仍然相信有一种方法可以存档这种文件完整性,只是我不知道。我想知道其他人是如何处理这个问题的。

这个问题与我的编程错误无关。那是另一个问题。当前的问题是保护数据免受其他不遵守建议文件锁定的程序的影响。而且,用户通常是 root 并且程序以相同的用户运行,所以琐碎的 Unix 文件权限是没有用的。

4

3 回答 3

4

您必须查看您试图通过强制锁定实际解决的问题。

强制锁定不能保证文件内容的完整性;除非您将文件锁定为 24/7;文件完整性仍然取决于所有遵守文件格式/访问约定的进程(并且仍然可能由于硬盘驱动器错误等而失败)。

强制锁定可以保护您免受编程错误(偶然,而不是出于恶意)未能遵守正确的锁定协议。同时,这种保护只是部分的,因为未能获得锁(无论是否强制)仍可能导致文件损坏。强制锁定还可以比需要的更多地减少可能的并发性。简而言之,强制锁定比建议锁定提供了更多针对软件缺陷的保护,但保护并不完整。

意外损坏问题的一种解决方案是使用经过积极测试以保持数据完整性的库。SQlite就是一个这样的库(还有其他库) (有关更多信息,另请参见此处此处)。在 OS X 上,Core Data在 SQLite 之上提供了一个抽象层作为数据存储。显然,这种方法应该辅以复制/备份,这样您就可以防止存储层无法帮助您的其他数据损坏原因(媒体故障、意外删除)。

通过限制对数据库的文件访问并仅允许通过网关(例如套接字或消息传递库)进行访问,可以获得额外的保护。然后你将只运行一个进程,它只是获取一个锁(并且永远不会释放它)。这个设置很容易测试;锁定只是为了防止网关进程的多个实例运行。

于 2013-05-03T17:08:23.480 回答
3

一种简单的解决方案是简单地对用户隐藏文件,直到您的程序完成使用它。

有多种方法可以隐藏文件。这取决于您是在修改以前对用户可见的现有文件还是创建新文件。即使修改现有文件,最好创建一个隐藏的工作副本,然后自动将其内容与用户可见的文件交换。

隐藏文件的一种方法是在用户通常不可见的位置创建文件。(也就是说,用户不必完全无法访问该文件,只是让他们不会绊倒它。)您可以使用和传递前两个参数来获得这样-[NSFileManager URLForDirectory:inDomain:appropriateForURL:create:error:]的位置. 有关如何以原子方式将文件移动到其文件位置的方法,请参见方法。NSItemReplacementDirectoryNSUserDomainMask-replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:

您可以使用各种 API 将文件设置为隐藏。您可以使用-[NSURL setResourceValue:forKey:error:]与键NSURLIsHiddenKey。您可以使用chflags()系统调用来设置UF_HIDDEN. 旧的 Unix 备用是使用以句点 ('.') 开头的文件名。

于 2013-05-04T09:57:54.477 回答
1

以下是有关此主题的一些详细信息: https ://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileCoordinators/FileCoordinators.html

现在我认为 OSX 的基本策略是这样的。

  • 始终允许任何进程访问。
  • 始终为共享数据文件的变化做好准备。
  • 当其他进程改变文件内容时得到通知,并对其提供适当的响应。例如,如果其他进程试图访问该文件,您可以向最终用户显示错误。然后用户会知道这很糟糕,并且不会再这样做了。
于 2014-06-15T22:29:31.260 回答