FileSystemWatcher - 识别已删除文件夹中的文件

时间:2014-04-09 16:34:48

标签: c# vb.net

我的FileSystemWatcher有另一个问题;) 简单地说,我想做什么:

我想观看特定的文件夹,以便将文件的路径添加到List(Of String)中,并为每个新文件设置一个整数变量。

所以:

我创建文件" Test.png"它就是这样做的:

(List) categoryFilesList.Add(e.FullPath)
(Integer-variable) counter += 1

嗯,这很好用。

现在,如果再次删除文件,它应该从列表中删除路径并再次设置整数变量。 ( - = 1)。

这也运作良好,但现在我遇到了问题,我无法找到解决方案。 我将IncludeSubdirectories设置为true以扫描子目录中的文件。添加此工作正常,但删除它不会。

那是因为我不向列表添加文件夹,只添加文件。所以,如果我删除一个文件夹,我无法知道它包含的内容和文件的数量,因为它已经消失了。

但是我想知道,有多少文件以及它们的路径是从列表中再次删除它们并再次将整数变量设置为删除文件的数量。

我无论如何都要在改变时保存它,但我不知道具体是什么,如果这是一个好主意。 有更好的解决方案吗?

如果有什么不清楚,那么我很抱歉,然后问。 我也接受C#-answers,VB.NET只是因为我的朋友想要的。

谢谢!

2 个答案:

答案 0 :(得分:2)

我担心这是不可能的,因为删除目录在系统中的工作方式。目录被删除,但递归的文件只是目录的一部分。

这很好地描述了here on MSDN forums

  

我会看到桌面上垃圾桶的行为,你会看到   每次删除文件夹时,都可以看到该文件夹   垃圾,但你看不到该删除文件夹中的元素。该   只能看到那些元素的方法是从中恢复文件夹   垃圾桶。

     

我认为它与FSW类发生的情况相同。当你删除   监视目录中的文件夹,您只有该事件   删除文件夹,因为文件夹及其内容不是真的   删除但只移到了垃圾箱。这就是你永远不会收到的原因   删除了包含文件的事件,因为它们仍在某处   在你的系统上

根据this question here on SO,当文件夹移动到结构中时会出现同样的问题(问题还显示移动问题的解决方法)。

删除问题的可能解决方法是提前浏览结构并将目录中的文件数量保存为树状结构,但肯定会比这复杂得多。它看起来像这样:

public class DirectoryFiles
{
    public int Count {get; set;}

    public string FullPath {get; set;}
    public List<DirectoryFiles> Subdirectories {get; set; }
}

private DirectoryFiles Initialize(string fullPath)
{
    if (Directory.Exists(fullPath))
    {
        var toReturn = new DirectoryFiles { Subdirectories = new List<DirectoryFiles>() };

        foreach (string directory in Directory.GetDirectories(fullPath))
        {
            toReturn.Subdirectories.Add(this.Initialize(directory));
        }

        toReturn.Count = toReturn.Subdirectories.Sum(x => x.Count) + Directory.GetFiles(fullPath).Count();
        return toReturn;
    }
    else
    {
        throw new DirectoryNotFoundException(String.Format("Directory {0} does not exist", fullPath));
    }
}

在您计算的班级中:

private int GetCountOfFiles(DirectoryFiles files, string fullPath)
{
    if (files.FullPath.Equals(fullPath, StringComparison.InvariantCultureIgnoreCase))
    {
        return files.Count;
    }
    foreach (var subdir in files.Subdirectories)
    {
        if (this.GetCountOfFiles(subdir, fullPath) != -1)
        {
            return subdir.Count;
        }
    }
    return -1;
}

这可能需要改进:

  • 权限 - 如果您无法访问这些文件,则会抛出异常
  • 性能并不完美,在每个子文件或子目录删除时,您都需要重建整个结构。也可以为此创建一些优化,但对于较小的子目录应该可以很好地工作。如果您需要改进性能,我会留给您。为此,请考虑将DirectoryFiles Parent添加到DirectoryFiles并重新计算目录。

答案 1 :(得分:2)

我对类似问题的解决方案如下: 确保您的FileSystemWatcher配置为跟踪子文件夹。一旦这样做,您应该在删除文件夹或文件时获得Delete事件。在删除文件夹的情况下,只需遍历您的集合并删除包含该文件夹路径的所有项目。

例如:

int numRemoved = categoryFilesList.RemoveAll(
            delegate(String s)
            {
               return s.Contains(<DeletedDirectoryPath>);
            }
            );

这会删除列表中包含的所有项目。然后,您可以使用numRemoved来维护文件计数。或者,您只需使用列表的计数,而不是通过列表中的Count属性维护您自己的数据副本。

此外,您应该确保处理重命名项目和目录的情况,以便您的文件名列表始终是最新的。