【问题标题】:Too Many Files Open while monitoring file changes监视文件更改时打开的文件过多
【发布时间】:2020-08-10 15:16:21
【问题描述】:

我正在为 iPad 开发一个基于文档浏览器的应用程序。我一直在使用SKQueue 来监视文件的更改,以确保当用户在文档浏览器中执行操作时它们的元数据保持最新。启动监控代码:

    // Set up the queue
    let delegate = self
    queue = SKQueue(delegate: delegate)!
    // Remove all existing paths
    queue?.removeAllPaths()

    // Get the list of PDF URLs using a function that enumerates a folder's contents
    let pdfFiles = getFolderContents(rootFolder: myDocumentsFolder, extensionWanted: "pdf")
    for pdfFilePath in pdfFiles.filePaths {
        queue?.addPath(pdfFilePath.path)
    }
    for pdfFolderPath in pdfFiles.folderPaths {
        queue?.addPath(pdfFolderPath.path)
    }

我开发了自己的逻辑来响应来自该队列的通知,但在应用运行期间我没有从队列中删除任何项目。

问题 - 似乎当观看的项目数量超过 200(文件和文件夹)时,系统会遇到问题,并且控制台会报告错误 24:打开的文件过多。之后就不能再读/写任何文件了。

根据我从搜索中收集到的信息,iOS 和 iPadOS 似乎不允许同时访问超过 256 个文件描述符,这意味着 GCD 监控文件更改的方法会受到影响相同的限制。

是否有任何方法可以监控不受此类限制的文件更改?还有其他建议吗?

【问题讨论】:

    标签: ios swift monitoring grand-central-dispatch ipados


    【解决方案1】:

    经过大量的研究和实验,我终于可以验证,打开文件描述符的默认最大数量是 256 - 对于 MacOS、iOS 和 iPadOS。这可以在 MacOS 中轻松更改 - 请参阅文章 here。然而,iOS 和 iPadOS 在本质上更加封闭,没有可靠的方法来改变这些平台上的这一限制。

    因此,良好做法是:

    1. 尽量避免设计一个需要打开这么多文件描述符的应用。
    2. 监控目录,而不是单个文件。借助大多数可用于监视文件系统的工具,您可以收到有关受监视目录中任何文件更改的通知。只需从那里通过枚举文件夹并将其新状态与保存的状态进行比较来实现您的逻辑。您可以在 SO thread 的前两个答案中找到很好的代码。

    注意:我建议使用枚举而不是其他获取文件系统状态的方法,因为其他方法往往会在模拟器和实际设备之间产生不兼容的结果(对符号链接分辨率的不同处理)。

    1. 确保您选择的监视文件系统的方法可以查询正在监视的项目数,并在用户接近设定的限制时发出警报。请记住,256 个打开的文件还必须包括应用程序使用的所有文件,包括应用程序包中的文件和实际使用的文件。所以要留出一个不错的安全边际。

    就我而言,我的应用程序使用 UIDocumentBrowserViewController,或者换句话说 - Apple 自己的文件应用程序,以允许用户管理他们的文件。我必须使我的元数据与文件系统状态保持同步,而且我无法控制用户的文件管理习惯。更复杂的是,文件应用程序本身可用于修改应用程序的文件系统 - 而我的应用程序未处于活动状态。

    因此,我做了两件事:

    1. 我将文件系统的详细状态从 App Delegate 的 applicationDidEnterBackground 和 applicationWillTerminate 方法保存到 Application Support 中的 json 文件中,并在应用程序启动时将其与文件系统的新枚举进行比较 - 并提醒用户如有不符之处,建议下次使用应用自带的文件浏览器。
    2. 我创建了自己的 swift 包,名为 SFSMonitor,用于监控文件系统。它基于非常方便的SKQueue(我强烈推荐),但它不是监控 kevent,而是使用 Dispatch Sources - Apple 提倡的更现代的方法。它类似于 Apple 自己的 Directory Monitor(您可以找到 here 的参考),但它不是监视一个目录,而是允许您创建和管理它们的整个队列。此类允许您设置受监控文件描述符的最大数量,并在达到该限制时收到通知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-21
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多