其他分享
首页 > 其他分享> > android-如何知道由文件观察器监视的已删除文件是目录还是文件

android-如何知道由文件观察器监视的已删除文件是目录还是文件

作者:互联网

我正在使用FileObserver监视文件夹中的更改.

事件按预期方式触发,但是在事件DELETE和MOVED_FROM中区分文件和目录时遇到问题,因为触发事件后,同时调用File.isFile()和File.isDirectory()都是错误的(这很有意义) .

有没有一种有效的方法可以在删除文件之前进行此检查?通过列出受影响文件夹中的所有文件,我确实有一种解决方法,但是效率不高.

Fileobserver代码:

 mFileObserver = new FileObserver(DIRECTORY.getPath()) {
            @Override
            public void onEvent(int event, String path) {
                event &= FileObserver.ALL_EVENTS;
                switch (event) {
                    case (CREATE):
                    case (MOVED_TO):
                        Log.d(TAG, "Added to folder: " + DIRECTORY + " --> File name " + path);
                        addChild(path);
                        break;
                    case (DELETE):
                    case (MOVED_FROM):
                        Log.d(TAG, "Removed from folder " + DIRECTORY + " --> File name " + path);                            
                        removeChild(path);
                        break;
                    case (MOVE_SELF):
                    case (DELETE_SELF):
                        removeDirectory();
                        break;
                }
            }               
        };

编辑:

这是在removeChild(String)中如何评估文件/文件夹的方式

private void removeChild(String name) {

        mFileObserver.stopWatching();

        String filepath = this.getAbsolutePath() + separator + name;
        File file = new File(filepath);
        if (file.exists())
            Log.d(TAG, "Exists");
        else Log.d(TAG, " Does not Exists");

        if (file.isDirectory())
            Log.d(TAG, "is Directory");
        else Log.d(TAG, " is  NOT Directory");

        if (file.isFile())
            Log.d(TAG, "is File");
        else Log.d(TAG, " is  NOT File");
    }

相关的logcat输出为:

04-03 12:37:20.714 5819-6352:  Removed from folder /storage/emulated/0/Pictures/GR --> File name ic_alarm_white_24dp.png
04-03 12:37:20.714 5819-6352:  Does not Exists
04-03 12:37:20.714 5819-6352:  is  NOT Directory
04-03 12:37:20.714 5819-6352:  is  NOT File

解决方法:

Is there an efficient way to make this check before file is removed?

不幸的是,我并不知道.这很有意义-文件系统事件是已经发生的事情.

FileObserver uses inotify获得事件.关于inotify功能的很好描述可以在https://www.ibm.com/developerworks/library/l-inotify/找到:

Monitor Linux file system events with inotify

Before inotify there was dnotify. Unfortunately, dnotify had
limitations that left users hoping for something better. Some of the
advantages of inotify are:

  • Inotify uses a single file descriptor, while dnotify requires opening one file descriptor for each directory that you intend to
    watch for changes. This can be very costly when you are monitoring
    several directories at once, and you may even reach a per-process file
    descriptor limit.
  • The file descriptor used by inotify is obtained using a system call and does not have an associated device or file. With dnotify, the file
    descriptor pins the directory, preventing the backing device to be
    unmounted, a particular problem with removable media. With inotify, a
    watched file or directory on a file system that is unmounted generates
    an event, and the watch is automatically removed.
  • Inotify can watch files or directories. Dnotify monitors directories, and so programmers had to keep stat structures or an
    equivalent data structure reflecting the files in the directories
    being watched, then compare those with the current state after an
    event occurred in order to know what happened to the entry in the
    directory.
  • As noted above, inotify uses a file descriptor, allowing programmers to use standard select or poll functions to watch for
    events. This allows for efficient multiplexed I/O or integration with
    Glib’s mainloop. In contrast, dnotify uses signals, which programmers
    often find more difficult or less than elegant. Signal-drive I.O
    notification was also added to inotify in kernel 2.6.25.

The API for inotify

请注意,这里没有提及“即将发生的事件”或类似事件.

您不需要保留所有文件的列表-您只需要目录列表-简单的Set< String>应该做得很好.如果已删除的String路径在集合中,则它是一个目录.

对于更健壮的方法,在启动监视时,还可以将FileObserver监视放置在您主要监视的目录中的所有目录上(也可以在创建监视程序后将监视添加到在主目录中创建的每个目录中) .

然后,如果您从子FileObserver对象之一获得DELETE_SELF,您将知道它是一个目录.如果该事件没有具有DELETE_SELF事件的关联子FileObserver对象,则它不是目录.

对于一个非常大的目录,这种方法无疑会存在可伸缩性问题…

标签:file,android,fileobserver
来源: https://codeday.me/bug/20191109/2011896.html