gpt4 book ai didi

android - 如何知道 File Observer 监视的已删除文件是目录还是文件

转载 作者:太空宇宙 更新时间:2023-11-03 13:42:14 26 4
gpt4 key购买 nike

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

事件按预期触发,但我无法区分事件 DELETEMOVED_FROM 中的文件和目录,因为在触发事件后,同时调用 File.isFile()File.isDirectory() 为 false(这是有道理的)。

在删除文件之前是否有一种有效的方法来进行此检查?我确实有一个解决方法,可以列出受影响文件夹中的所有文件,但效率很低。

文件观察者代码:

 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 path在集合中,它是一个目录。

为了获得更稳健的方法,当您启动 watch 时,您还可以将 FileObserver监视您主要监视的目录中的所有目录(还可以在创建监视程序后向主目录中创建的每个目录添加一个监视)。

然后如果你得到一个DELETE_SELF来自其中一个 child FileObserver对象,你会知道它是一个目录。如果事件没有关联的子项 FileObserver获得 DELETE_SELF 的对象事件,它不是目录。

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

关于android - 如何知道 File Observer 监视的已删除文件是目录还是文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49628236/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com