FileObserver创建或删除只对文件接收或删除、只对、文件、FileObserver

2023-09-05 08:41:31 作者:血狱

我已经注册了一个FileObserver一个目录。

I've registered a FileObserver for a directory.

this.observer = new DirectoryObserver(requested.getAbsolutePath(),
        FileObserver.CREATE | FileObserver.DELETE | FileObserver.DELETE_SELF);
this.observer.startWatching();

在测试了奇巧模拟器。 亚行的shell:

Tested on KitKat emulator. adb shell:

root@generic:/sdcard # echo "test" >> test.txt //notified CREATE
root@generic:/sdcard # rm test.txt //notified DELETE
root@generic:/sdcard # mkdir test //no events received
root@generic:/sdcard # rmdir test //no events received 

在DirectoryObserver仅供参考

The DirectoryObserver for reference

private final class DirectoryObserver extends FileObserver {

    private DirectoryObserver(String path, int mask) {
        super(path, mask);
    }

    @Override
    public void onEvent(int event, String pathString) {
        switch (event) {
            case FileObserver.DELETE_SELF:
                //do stuff
                break;

            case FileObserver.CREATE:
            case FileObserver.DELETE:
                //do stuff
                break;
        }
    }
}

从文档

CREATE
Event type: A new file or subdirectory was created under the monitored directory 

DELETE
Event type: A file was deleted from the monitored directory 

因此​​,对于创建我应该得到的文件和目录,只对文件中删除? 嗯,我还没有收到为其创建子目录。

So for CREATE I should receive for files and directories and on DELETE only for files? Well, I still don't receive CREATE for a subdirectory.

推荐答案

这样做的原因是,Android不抽象了底层的文件系统不够好,并返回底层事件code有一些凸起的标志(部分在事件的高位)。这就是为什么在事件类型直接不起作用。

The reason of this is that android does not abstract over underlying file system well enough and returns underlying event code with some of the flags raised (some of the higher bits of the event). This is why comparing the event value with the event type directly does not work.

要解决这个问题,你可以通过应用降额外标志 FileObserver.ALL_EVENTS 事件掩码(使用位运算符和)实际 事件值剥离下来为事件类型

To solve this you can drop extra flags by applying FileObserver.ALL_EVENTS event mask (using bitwise and) to actual event value stripping it down to event type.

使用你提问中所提供的code,这将是这个样子:

Using the code you've provided in your question this will look something like this:

private final class DirectoryObserver extends FileObserver {

    private DirectoryObserver(String path, int mask) {
        super(path, mask);
    }

    @Override
    public void onEvent(int event, String pathString) {
        event &= FileObserver.ALL_EVENTS;
        switch (event) {
            case FileObserver.DELETE_SELF:
                //do stuff
                break;

            case FileObserver.CREATE:
            case FileObserver.DELETE:
                //do stuff
                break;
        }
    }
}