File Watcher控制台应用程序在执行一次后关闭

时间:2018-06-15 21:04:55

标签: c# .net

我有一个监视目录的控制台应用程序,它只运行一次,我需要应用程序继续运行并查看文件目录。

代码还检查文件是否已经存在,如果是,那么它会移动它,没有它应该等待和观察,但等待和观察没有发生。

这是代码

class Program
    {
        public static String stagepath = @"C:\Users\a\Desktop\.NET Data Loader\stage\";
        public static String archivePath = @"C:\Users\a\Desktop\.NET Data Loader\archive\";
        static void Main(string[] args)
        {
            DirectoryInfo dirinfo = new DirectoryInfo(stagepath);
            FileInfo[] file = dirinfo.GetFiles();
            if (file.Length > 0)
            {
                MoveFile(stagepath);
            }
            else
            {

                MonitorDirectory(stagepath);
            }


        }

        public static void MonitorDirectory(string path)
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = path;
           watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Changed += FileCreated;
            watcher.EnableRaisingEvents = true;


        }

        private static void FileCreated(object sender, FileSystemEventArgs e)
        {
            if (!FileIsReady(stagepath+e.Name)) return;
            System.Threading.Thread.Sleep(1000);

            MoveFile(stagepath);



        }

        private static  bool FileIsReady(string path)
        {
            try
            {
                using (var file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    return true;
                }
            }
            catch (IOException)
            {
                return false;
            }
        }

        private static void MoveFile(string path)
        {

            string[] fileNames = Directory.GetFiles(path);
            var sort = from fn in fileNames
                       orderby new FileInfo(fn).Name ascending
                       orderby new FileInfo(fn).LastWriteTime ascending
                       select new FileInfo(fn).Name;
            foreach (string fi in sort)
            {

                System.IO.File.Move(stagepath +fi, archivePath+fi);
                Console.WriteLine($"File {fi} has been sucessfully moved ");
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

放置将文件移动到循环中的代码,例如while循环。确保在每个循环后放置一个Thread.Sleep。 MSDN - Thread.Sleep

初始化时,只需将FileSystemWatcher的事件连接一次。

可能会想要一种退出循环的方法,除非杀死进程就足够了。

<强>更新

我对它进行了修改,因此不需要循环。您将不得不对其进行一些修改以获得您想要的结果,但至少现在您有一个有效的例子。在将来使用Visual Studio / IDE调试器时,原始示例中存在许多错误。

您的问题特别是您的文件路径将路径和文件名一起阻塞,例如位于C:\ temp \ foo.txt的文件将变为C:\ tempfoo.txt。然后你检查文件是否可以在移动之前打开,但由于格式错误的路径不存在而无法打开。此外,控制台只需要保持打开状态,不需要循环。只是移动文件的代码有错误,事件仍然被正确触发。您可能希望从FileCreatedInMonitoredDirectory事件处理程序中删除睡眠,我认为不需要它,但我将其保留在那里,因为它是最初的原因。

using System;
using System.IO;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        private static string _monitoringPath = @"C:\temp";
        private static string _destinationPath = @"C:\dest";
        static void Main(string[] args)
        {
            MonitorDirectory(_monitoringPath);
            Console.ReadKey();
        }

        public static void MonitorDirectory(string path)
        {
            var watcher = new FileSystemWatcher();
            watcher.Path = path;
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Changed += FileCreatedInMonitoredDirectory;
            watcher.EnableRaisingEvents = true;
        }

        private static void FileCreatedInMonitoredDirectory(object sender, FileSystemEventArgs e)
        {         
            MoveFilesInDirectory(_monitoringPath);

            System.Threading.Thread.Sleep(1000);
        }

        private static bool CanFileBeOpened(string path)
        {
            try
            {
                using (var file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
                    return true;
            }
            catch (IOException ioEx)
            {
                Console.WriteLine($"Warning: File could not be opened, it will not be moved. {ioEx}" );
                return false;
            }
        }

        private static void MoveFilesInDirectory(string dirPath)
        {
            string[] fileNames = Directory.GetFiles(dirPath);
            var sortedFileNames = from fn in fileNames
                                  orderby new FileInfo(fn).Name ascending
                                  orderby new FileInfo(fn).LastWriteTime ascending
                                  select new FileInfo(fn).Name;

            foreach (string fileName in sortedFileNames)
            {
                string filePath = Path.Combine(_monitoringPath, fileName);

                if (!CanFileBeOpened(filePath))
                    continue;

                var fileInfo = new FileInfo(filePath);
                if (fileInfo.Length > 0)
                {
                    File.Move(Path.Combine(_monitoringPath, fileName), Path.Combine(_destinationPath, fileName));
                    Console.WriteLine($"File {fileName} has been moved successfully.");
                }
            }
        }
    }
}

答案 1 :(得分:0)

您只需更改以下代码:

    static void Main(string[] args)
    {
        DirectoryInfo dirinfo = new DirectoryInfo(stagepath);
        FileInfo[] file = dirinfo.GetFiles();
        if (file.Length > 0)
        {
            MoveFile(stagepath);
        }
        else
        {

            MonitorDirectory(stagepath);
        }
        Console.ReadKey();

    }

当您使用文件观察程序时,另一个线程会在您运行应用程序之前保持活动状态。所以你需要让你的应用程序运行任何策略。