是否可以观看文件,看看它何时被阅读?

时间:2015-04-24 11:49:46

标签: c# .net file filesystems monitoring

我有一个文件,它很大,阅读需要很长时间,而且我想进行一些监控以查看它何时被写入。

我可以通过将一些日志记录到读取它的应用程序中来轻松解决这个问题,但是我想要一些更不可知的东西。有很多应用程序具有类似的用例。监控写入应该很容易,因为我可以观看上次修改日期,但阅读并不那么容易。

有没有办法被动监控对文件的读写?

澄清一下:如果它可以在100%C#中完成,那么很好,如果不是那么炮轰到其他'东西',或者甚至诉诸其他语言也没关系。我真的不介意观看的内容是什么。

尝试Rahul的解决方案

我已经设置了以下测试代码。它将事件转储到控制台:

public static void Main()
{
    var taskFactory = new TaskFactory();
    var setup = new Action(() =>
    {
        var setupWatcher =
            new Action<NotifyFilters, string, FileSystemWatcher>((filters, s, watcher) =>
            {
                watcher.EnableRaisingEvents = true;
                watcher.NotifyFilter = filters;
                watcher.Changed += (sender, args) => System.Console.WriteLine(s, args.FullPath, args.ChangeType);
            });


        var lastAccessWatcher = new FileSystemWatcher(BASE_PATH);
        setupWatcher(NotifyFilters.LastAccess,
            "File: {0}\tFilter: LastAccess\tType: {1}", lastAccessWatcher);

        var lastWriteWatcher = new FileSystemWatcher(BASE_PATH);
        setupWatcher(NotifyFilters.LastWrite, "File: {0}\tFilter: LastWrite\tType: {1}",
            lastWriteWatcher);

        var fileNameWatcher = new FileSystemWatcher(BASE_PATH);
        setupWatcher(NotifyFilters.FileName,
            "File: {0}\tFilter: FileName\tType: {1}", fileNameWatcher);

        var directoryNameWatcher = new FileSystemWatcher(BASE_PATH);
        setupWatcher(NotifyFilters.LastWrite, "File: {0}\tFilter: DirectoryName\tType: {1}",
            directoryNameWatcher);
    });

    taskFactory.StartNew(setup);

    while (true)
    {
        Thread.Sleep(10);
    }
}

但是,当我在记事本中打开文本文件时,lastAccessWatcher不会抛出任何事件,而当我保存时,lastWriteWatcher会抛出两个事件以及directoryNameWatcher,如下所示。

File: F:\FileMonitor\New Text Document.txt      Filter: LastWrite       Type: Changed
File: F:\FileMonitor\New Text Document.txt      Filter: LastWrite       Type: Changed
File: F:\FileMonitor\New Text Document.txt      Filter: DirectoryName   Type: Changed
File: F:\FileMonitor\New Text Document.txt      Filter: DirectoryName   Type: Changed

因此...

  1. 触发“上次访问”的内容
  2. 读取文件时,我是否可以触发任何触发器?

4 个答案:

答案 0 :(得分:2)

为了观看对文件的写入,FileSystemWatcher类是正确的方法。但是,如果您想知道是否正在编写文件,我要做的是按进程获取所有打开文件的列表,并监视文件何时打开然后关闭。

There is a CodeProject article that shows how to get the open files by process here.

答案 1 :(得分:1)

您可以使用FileSystemWatcher class

  

收听文件系统更改通知并在何时引发事件   目录或目录中的文件发生更改。

您可以使用不同的活动

并阅读此FileSystemWatcher Tips

一个例子:

public void MyFileWatcher(string path)
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = path;
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
       | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    watcher.Filter = "myFile.txt";
    watcher.Changed += new FileSystemEventHandler(OnChanged);    
    watcher.EnableRaisingEvents = true;
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
   Console.WriteLine(e.FullPath + " " + e.ChangeType);
}

同样,您可以添加其他事件处理程序定义。

此外,如果您想检查读取,那么您可以在轮询循环中使用FileInfo.LastAccessTimeFileInfo.Refresh()来获取有关何时读取文件的信息。

答案 2 :(得分:1)

一种解决方案是使用名为Process Monitor的Microsoft工具。它可以列出任何进程执行的所有CreateFile / ReadFile / WriteFile调用。有几个命令行选项可用:

enter image description here

答案 3 :(得分:0)

在代码中,您的任务由文件系统过滤器驱动程序处理。 Process Monitor应用程序(已在另一个答案中提到)包括预构建形式的此类驱动程序。

你可以自己编写内核模式驱动程序,但这可能是一种过度杀伤力。然后存在我们的CallbackFilter - 一个包含预先创建的内核模式驱动程序的类库。您在C#中编写代码并在执行之前或之后捕获所有文件系统操作。如果您的需求是短期的,那么评估许可证将起作用。