监视文件更改时打开的文件太多 [英] Too Many Files Open while monitoring file changes

查看:58
本文介绍了监视文件更改时打开的文件太多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am developing a document-browser-based app for the iPad. I have been using SKQueue to monitor changes to the files in order to make sure their metadata remains current when the user performs actions in the document browser. The code for initiating monitoring:

    // 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)
    }

我开发了自己的逻辑来响应来自此队列的通知,但是在应用程序运行时,我没有从队列中删除任何项目.

I developed my own logic to respond to notifications from this queue, but I do not remove any items from the queue during the app's runtime.

问题-似乎当观看的项目数超过200(文件和文件夹)时,系统撞墙并且控制台报告错误24:打开的文件太多.之后,将无法执行任何文件的读取/写入.

The problem - it seems that when the number of items watched is over 200 (files and folders) the system hits a wall and the console reports error 24: Too Many Files Open. After that, no reading/writing of any file can be performed.

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

From what I was able to gather from searching, it seems that iOS and iPadOS do not allow more than 256 files descriptors to be accessed at the same time, and that would mean that the GCD approach to monitoring file changes would suffer from the same limitation.

有没有什么方法可以监视不受此限制的文件更改?还有其他建议吗?

Is there any way to monitor files changes that is not subject to such a limitation? Any other suggestions?

推荐答案

经过大量研究和实验,我终于可以确认确实,打开文件描述符的默认最大允许数目是256-对于MacOS,iOS和iPadOS.在MacOS中可以轻松更改此设置-请参见文章此处.但是,iOS和iPadOS本质上更加封闭,在这些平台上没有可靠的方法来更改此限制.

After a lot of research and experimentation, I can finally verify that indeed, the default maximum number allowed of open file descriptors is 256 - for MacOS, iOS and iPadOS. This can be changed easily in MacOS - see article here. However, iOS and iPadOS being much more closed in nature, there is no reliable way of changing this limit on these platforms.

因此,好的做法是:

  1. 尝试避免设计会调用太多文件描述符的应用.
  2. 监控目录,而不是单个文件.使用大多数可用于监视文件系统的工具,您会收到有关受监视目录中任何文件更改的通知.通过枚举文件夹并将其新状态与保存状态进行比较,只需从那里实施逻辑即可.您可以在此 SO线程的前两个答案中找到合适的代码.
  1. Try to avoid designing an app that would call for so many file descriptors open.
  2. Monitor directories, and not individual files. With most tools available for monitoring the file system, you get notifications for any file change within a monitored directory. Just implement your logic from there, by enumerating the folder and comparing its new state with a saved state. You can find good code for that in the top two answers of this SO thread.

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

Note: I recommend enumeration rather than other methods of getting the file system state, because other methods tend to give incompatible results between the simulator and actual devices (different treatment of symlink resolution).

  1. 确保可以查询您选择的监视文件系统的方法以查看正在监视的项目数,并在用户接近设置的限制时发出警报.请记住,这256个打开的文件还必须包括该应用程序使用的所有文件,包括应用程序捆绑包中的文件和实际使用的文件.因此,请注意安全性.

就我而言,我的应用程序使用UIDocumentBrowserViewController或换句话说-Apple自己的Files应用程序,以允许用户管理其文件.我必须使元数据与文件系统状态保持最新,并且无法控制用户的文件管理习惯.使事情变得复杂的是,文件"应用程序本身可以用于修改该应用程序的文件系统-当我的应用程序不活动时.

In my case, my app uses a UIDocumentBrowserViewController, or in other words - Apple's own Files app, to allow users to manage their files. I have to keep my metadata up-to-date with the file system state, and I have no control over the file management habits of my users. To complicate matters, the Files app itself can be used to modify the app's file system - while my app is not active.

因此,我要做两件事:

  1. 我将App Delegate的applicationDidEnterBackground和applicationWillTerminate方法的文件系统的详细状态保存到Application Support中的json文件中,并在应用程序启动时将其与文件系统的新枚举进行比较-并提醒用户注意任何不匹配的内容,建议下次使用该应用程序自己的文件浏览器.
  2. 我创建了自己的快速软件包,名为 SFSMonitor ,用于监视文件系统.它基于非常方便的 SKQueue (我强烈建议),但它不是监视kevent,它使用了Apple倡导的Dispatch Sources(一种更现代的方法).它类似于苹果自己的目录监视器(您可以在此处找到该目录监视器),但它不是监视一个目录,而是允许您创建和管理它们的整个队列.此类允许您设置最大数量的受监视文件描述符,并在达到该限制时得到通知.
  1. I save a detailed state of the file system from the App Delegate's applicationDidEnterBackground and applicationWillTerminate methods into a json file in Application Support, and on the app's launch I compare it to a fresh enumeration of the file system - and alert the user for any mismatch, suggesting to use the app's own file browser next time.
  2. I created my own swift package, named SFSMonitor, for monitoring the file system. It is based on the wonderfully convenient SKQueue (which I highly recommend), but instead of monitoring kevent, it uses Dispatch Sources - a more modern approach, which Apple advocates. It is similar to Apple's own Directory Monitor (reference to which you can find here), but instead of monitoring one directory, it allows you to create and manage a whole queue of them. This class allows you to set a maximum number of monitored file descriptors, and be notified when that limit is reached.

这篇关于监视文件更改时打开的文件太多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆