目录扫描器Windows服务与FileSystemWatcher



我正在尝试创建一个windows服务,它将抓取上传到目录的新文件,编辑它们并移动到其他目录。似乎我可以复制它们,但不能移动。为什么呢?

using System;
using System.ServiceProcess;
using System.Threading;
using System.IO;
namespace ImportService
{
    public class ImportServer : ServiceBase
    {        
        private System.Diagnostics.EventLog eventLog1;
        private FileSystemWatcher watcher;
        public ImportServer()
        {
            this.ServiceName = "ImportService";
            this.CanHandlePowerEvent = true;
            this.CanHandleSessionChangeEvent = true;
            this.CanPauseAndContinue = true;
            this.CanShutdown = true;
            this.CanStop = true;
            this.AutoLog = true;           
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("ImportServiceLogSource"))
                System.Diagnostics.EventLog.CreateEventSource("ImportServiceLogSource", "ImportServiceLog");
            eventLog1.Source = "ImportServiceLogSource";
            eventLog1.Log = "ImportServiceLog";
        }
        public static void Main()
        {
            ServiceBase.Run(new ImportServer());            
        }        
        protected override void OnStart(string[] args)
        {
            //base.OnStart(args);
            eventLog1.WriteEntry("service started");
            watcher = new FileSystemWatcher();
            watcher.Path = "C:\INPUT\";
            watcher.Filter = "*.jpg";
            watcher.EnableRaisingEvents = true;
            watcher.Created += new FileSystemEventHandler(OnCreated);            
        }
        private void OnCreated(object sender, FileSystemEventArgs e)
        {
            String output_dir = "C:\OUTPUT\";
            String output_file = Path.Combine(output_dir, e.Name);
            File.Move(e.FullPath, output_file);
            // File.Copy() works here
            eventLog1.WriteEntry("moving file to " + output_file);
        }
        protected override void OnStop()
        {            
            eventLog1.WriteEntry("service stopped");
            base.OnStop();
        }
        protected override void OnContinue()
        {
            base.OnContinue();
        }
        protected override void OnPause()
        {
            base.OnPause();
        }
        private void InitializeComponent()
        {
            this.eventLog1 = new System.Diagnostics.EventLog();
            ((System.ComponentModel.ISupportInitialize)(this.eventLog1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.eventLog1)).EndInit();
        }
    }
}

我也应该保留base.OnStart();等。它到底有什么用?

UPDATE:如何移动在监视目录中创建的文件?文件已在使用异常问题。

你必须捕获IOException并使线程休眠几位,然后再试一次。

private void OnCreated(object sender, FileSystemEventArgs e)
{
    String output_dir = "C:\OUTPUT\";
    String output_file = Path.Combine(output_dir, e.Name);
    while (true)
    {
        try
        {
            File.Move(e.FullPath, output_file);
            break;
        }
        catch (IOException)
        {
            //sleep for 100 ms
            System.Threading.Thread.Sleep(100);
        }
    }        
    eventLog1.WriteEntry("moving file to " + output_file);
}

话虽这么说,但这有很多问题。你最好有一个计时器事件,每隔几秒调用一次,在文件夹中查找文件。如果你得到一个IOException,你就继续。在下一次迭代中,该文件仍然在那里等待处理(假设上传已经完成)。如果你需要的话,我可以给你举个例子。

如果要避免服务崩溃,您的OnCreated实现需要处理异常。在处理文件时,很多事情可能会出错,当它们出错时,您的服务需要优雅地恢复。

这里的一种可能性是,在写入新文件的进程完成写入之前,OnCreated事件可能会触发,因此您尝试移动该文件时会抛出异常。

据我所知,您需要等待文件传输完成并关闭文件,然后才能移动文件。

这已经在SO上讨论过好几次了。如。这里和这里。

相关内容

  • 没有找到相关文章

最新更新