每次在文件夹中创建文件时如何使用filesystemwatcher并发送邮件? [英] How to use filesystemwatcher and send mail every time a file is created in a folder?

查看:90
本文介绍了每次在文件夹中创建文件时如何使用filesystemwatcher并发送邮件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在运行一个流程,它会在特定事件上创建文件并写入数据。文件在文件夹中创建:C:\\EventListenerFolder \\。现在每当创建一个新文件并将数据写入文件时,我们都需要发送邮件。





public static void RunEventListenerPrgm ()

{

//邮件通知必须在C:\\ EventListenerFolder \\
$ b生成文件时$ b while(true)

{

System.IO.FileSystemWatcher m_Watcher = new System.IO.FileSystemWatcher();

m_Watcher.Filter =* .txt;

m_Watcher.Path =C:\\EventListenerFolder \\;

m_Watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;

m_Watcher.Changed + = new FileSystemEventHandler(OnChanged);

m_Watcher.EnableRaisingEvents = true;

}

}



public static void OnChanged(object sender,FileSystemEventArgs e)

{

string stringReceived;

string [] allFiles = System.IO.Directory.GetFiles(C:\\ EventListenerFolder \\);

foreach(字符串文件in allFiles)

{

Console.WriteLine(EventListener找到匹配文件。文件名:+文件);

试试

{

stringReceived = System.IO.File.ReadAllText(file);

}

catch(Exception ex)

{

继续; //以避免在写入文件时读取文件。因此我们等到文件被写入然后我们才读到它

}

SendMailFunction(stringReceived);

File.Delete(file);



}

}



在这种情况下,我们得到100 +邮件为同一个文件。我们只想发送一个邮件发送给一个文件。



我尝试了什么:



尝试更改m_Watcher.Changed + = new FileSystemEventHandler(OnChanged);

到m_Watcher.Created + = new FileSystemEventHandler(OnChanged);

仍然不起作用。



可能是我正在使用的文件监视器事件过滤器不正确吗?

你可以帮我一下吗?

There is a process we are running, which creates files and writes data on a particular event. File is created in folder: C:\\EventListenerFolder\\ . Now whenever a new file is created and data is written to the file, we need to send a mail.


public static void RunEventListenerPrgm()
{
//the mail notification has to go as a file gets generated in C:\\EventListenerFolder\\
while (true)
{
System.IO.FileSystemWatcher m_Watcher = new System.IO.FileSystemWatcher();
m_Watcher.Filter = "*.txt";
m_Watcher.Path = "C:\\EventListenerFolder\\";
m_Watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
m_Watcher.Changed += new FileSystemEventHandler(OnChanged);
m_Watcher.EnableRaisingEvents = true;
}
}

public static void OnChanged(object sender, FileSystemEventArgs e)
{
string stringReceived;
string[] allFiles = System.IO.Directory.GetFiles("C:\\EventListenerFolder\\");
foreach (string file in allFiles)
{
Console.WriteLine("EventListener Match File Found. FILE NAME : " + file);
try
{
stringReceived = System.IO.File.ReadAllText(file);
}
catch (Exception ex)
{
continue; // to avoid reading of file when it is in process of being written . hence we wait till the file is written and then we read it
}
SendMailFunction(stringReceived);
File.Delete(file);

}
}

In this scenario, we are getting 100+ mail for the same file. And we want only one mail for one file to be sent.

What I have tried:

Tried changing m_Watcher.Changed += new FileSystemEventHandler(OnChanged);
to m_Watcher.Created+= new FileSystemEventHandler(OnChanged);
still doesnot work.

Could it be that the file watcher event Filter I am using is incorrect?
Could you please help me on the same?

推荐答案

这么多问题;从哪里开始? :)



您的 OnChanged 事件处理程序忽略了有关 文件已更改的信息,并为该文件夹中的所有文件发送通知。您应该使用 e.FullName 来处理已更改的文件:

So many problems; where to begin? :)

Your OnChanged event handler is ignoring the information about which file changed, and sending a notification for all files in the folder. You should use e.FullName to process just the file which has changed:
private static void OnChanged(object sender, FileSystemEventArgs e)
{
    string file = e.FullName;
    Console.WriteLine("EventListener Match File Found. FILE NAME : {0}", file);
    
    try
    {
        string stringReceived = File.ReadAllText(file);
        SendMailFunction(stringReceived);
        File.Delete(file);
    }
    catch (IOException)
    {
    }
}



您的 RunEventListenerPrgm 方法正在紧密循环中创建多个新的 FileSystemWatcher 实例。您创建的每个实例都会在每次更改文件时触发 OnChanged 处理程序。我很惊讶你只收到了一个单个文件的数百条消息!



该方法永远不会干净地终止,所以快速而肮脏的修复会是在循环之外移动 FileSystemWatcher 实例的创建:


Your RunEventListenerPrgm method is creating multiple new FileSystemWatcher instances in a tight loop. Every single instance you create is going to trigger the OnChanged handler every time a file is changed. I'm amazed that you only managed to receive hundreds of messages for a single file!

The method will never terminate cleanly, so a quick-and-dirty fix would be to move the creation of the FileSystemWatcher instance outside of the loop:

public static void RunEventListenerPrgm()
{
    var m_Watcher = new System.IO.FileSystemWatcher
    {
        Filter = "*.txt",
        Path = @"C:\EventListenerFolder\",
        NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName
    };
    
    m_Watcher.Created += OnChanged;
    m_Watcher.EnableRaisingEvents = true;
    
    while (true)
    {
    }
}



但是,一旦程序运行,这可能会占用你CPU核心的100%!



稍微好一点的选择是使用 WaitForChanged 方法:


However, this will probably consume 100% of one of your CPU cores all the time the program is running!

A slightly better alternative would be to use the WaitForChanged method:

public static void RunEventListenerPrgm()
{
    var m_Watcher = new System.IO.FileSystemWatcher
    {
        Filter = "*.txt",
        Path = @"C:\EventListenerFolder\",
        NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName
    };
    
    while (true)
    {
        WaitForChangedResult result = m_Watcher.WaitForChanged(WatcherChangeTypes.Created | WatcherChangeTypes.Changed);
        if (!result.TimedOut)
        {
            OnChanged(result.Name);
        }
    }
}

private static void OnChanged(string file)
{
    Console.WriteLine("EventListener Match File Found. FILE NAME : {0}", file);
    
    try
    {
        string stringReceived = File.ReadAllText(file);
        SendMailFunction(stringReceived);
        File.Delete(file);
    }
    catch (IOException)
    {
    }
}



理想情况下,您需要找到一些方法在应用程序关闭时通知方法,以便它可以干净地停止循环。



最后,有一个已知问题, FileSystemWatcher 可以为同一个更改生成多个事件。有很多可以找到的解决方法 - 例如:

FileSystemWatcher更改的事件被引发两次 - Stack Overflow [ ^ ]

FileSystemWatcher生成重复事件 - 如何解决方法 - BizTalk 2006 - Windows SharePoint Services适配器 [ ^ ]


Ideally, you'd need to find some way to notify the method when your application was closing, so that it could stop the loop cleanly.

Finally, there is a known issue where the FileSystemWatcher can generate multiple events for the same change. There are numerous workarounds to be found - for example:
FileSystemWatcher Changed event is raised twice - Stack Overflow[^]
FileSystemWatcher generates duplicate events – How to workaround – BizTalk 2006 – Windows SharePoint Services adapter[^]


这篇关于每次在文件夹中创建文件时如何使用filesystemwatcher并发送邮件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆