Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 缺少具有后台线程的FileSystemWatcher来移动文件_C#_Multithreading_Queue_Backgroundworker_Filesystemwatcher - Fatal编程技术网

C# 缺少具有后台线程的FileSystemWatcher来移动文件

C# 缺少具有后台线程的FileSystemWatcher来移动文件,c#,multithreading,queue,backgroundworker,filesystemwatcher,C#,Multithreading,Queue,Backgroundworker,Filesystemwatcher,我有一个将文件从源文件夹移动到目标文件夹的简单要求。这些文件的大小约为5mb,每次到达3个(每5秒) 我现在使用的机制似乎是移动文件,但是如果目标文件夹在几秒钟内无法访问,则要从源目录处理的文件不会排队,而是会丢失 我的问题是如何创建一个包含在源目录中创建的所有文件的队列,并将这些文件移动到目标?我需要使用后台线程吗 我的观察者代码如下所示 public sealed class Watcher { int eventCount = 0; #region

我有一个将文件从源文件夹移动到目标文件夹的简单要求。这些文件的大小约为5mb,每次到达3个(每5秒)

我现在使用的机制似乎是移动文件,但是如果目标文件夹在几秒钟内无法访问,则要从源目录处理的文件不会排队,而是会丢失

我的问题是如何创建一个包含在源目录中创建的所有文件的队列,并将这些文件移动到目标?我需要使用后台线程吗

我的观察者代码如下所示

public sealed class Watcher
    {
        int eventCount = 0;

        #region Private Members
        /// <summary>
        /// File system watcher variable.
        /// </summary>
        private FileSystemWatcher fsw = null;
        /// <summary>
        /// Destination path to use.
        /// </summary>
        private string destination = @"c:\temp\doc2\";
        /// <summary>
        /// Source path to monitor.
        /// </summary>
        private string source = @"c:\temp\doc\";
        /// <summary>
        /// Default filter type is all files.
        /// </summary>
        private string filter = "*.bmp";
        /// <summary>
        /// Monitor all sub directories in the source folder.
        /// </summary>
        private bool includeSubdirectories = true;
        /// <summary>
        /// Background worker which will Move files.
        /// </summary>
        private BackgroundWorker bgWorker = null;
        /// <summary>
        /// Toggle flag to enable copying files and vice versa.
        /// </summary>
        private bool enableCopyingFiles = false;
        /// <summary>
        /// File System watcher lock.
        /// </summary>
        private object fswLock = new object();

        private static Watcher watcherInstance;
        #endregion

        #region Public Properties
        public static Watcher WatcherInstance
        {
            get
            {
                if (watcherInstance == null)
                {
                    watcherInstance = new Watcher();
                }
                return watcherInstance;
            }
        }



        public string Source
        {
            get
            {
                return source;
            }
            set
            {
                source = value;
            }
        }

        public string Destination
        {
            get
            {
                return destination;
            }
            set
            {
                destination = value;
            }
        }

        public string Filter
        {
            get
            {
                return filter;
            }
            set
            {
                filter = value;
            }
        }

        public bool MonitorSubDirectories
        {
            get
            {
                return includeSubdirectories;
            }
            set
            {
                includeSubdirectories = value;
            }
        }

        public bool EnableCopyingFiles
        {
            get
            {
                return enableCopyingFiles;
            }
            set
            {
                enableCopyingFiles = value;
            }
        }

        public FileSystemWatcher FSW
        {
            get
            {
                return fsw;
            }
            set
            {
                fsw = value;
            }
        }
        #endregion

        #region Construction
        /// <summary>
        /// Constructor.
        /// </summary>
        public Watcher()
        {
            // Intentionally left blank.

        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Method which will initialise the required 
        /// file system watcher objects to starting watching.
        /// </summary>
        public void InitialiseFSW()
        {
            fsw = new FileSystemWatcher();
            bgWorker = new BackgroundWorker();
        }

        /// <summary>
        /// Method which will start watching.
        /// </summary>
        public void StartWatch()
        {
            if (fsw != null)
            {
                fsw.Path = source;
                fsw.Filter = filter;
                fsw.IncludeSubdirectories = includeSubdirectories;
                fsw.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastAccess;

                // Setup events.
                fsw.Created += fsw_Created;
                // Important to set the below otherwise no events will be raised.
                fsw.EnableRaisingEvents = enableCopyingFiles;
                bgWorker.DoWork += bgWorker_DoWork;
            }
            else
            {
                Trace.WriteLine("File System Watcher is not initialised. Setting ISS Fault Alarm Bit");
                //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
            }
        }

        /// <summary>
        /// Method to stop watch.
        /// </summary>
        public void StopWatch()
        {
            // Stop Watcher.
            if (bgWorker != null)
            {
                bgWorker.DoWork -= bgWorker_DoWork;
            }
            if (fsw != null)
            {
                fsw.Created -= fsw_Created;
            }
        }
        #endregion


        #region Private Methods
        /// <summary>
        /// Method which will do the work on the background thread.
        /// Currently Move files from source to destination and 
        /// monitor disk capacity.
        /// </summary>
        /// <param name="sender">Object Sender</param>
        /// <param name="e">Event Arguments</param>
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Trace.WriteLine("ZZZZZ..Event Count:" + eventCount.ToString());
            // Extract the file names form the arguments.
            FileSystemEventArgs fsea = (FileSystemEventArgs)e.Argument;
            // Form the correct filename.
            // An assumption has been made that there will always be an '&' symbol in the filename.
            // An assumption has been made that the batch code will be added before the first '&' symbol.

            string newFileName = string.Empty;

            //// First character we are looking for has been found.
            //// Sanity checks.
            //if (CommonActions.ExtDictionary != null)
            //{
            //    // Add the batch Code.
            //    // newFileName = fnParts[i] + "_" + CommonActions.ExtDictionary["BatchID"] + "_" + "&";
            //    // Add the batch code before the filename for easy sorting in windows explorer.
            //    newFileName = CommonActions.ExtDictionary["BatchID"] + "_" + fsea.Name;
            //}
            //else
            //{
            // Batch Code not found. So prefix with hardcoded text. 
            newFileName = "BatchCode" + "_" + fsea.Name;
            //newFileName = fsea.Name;
            //}


            // We should now have the fully formed filename now. 
            // Move the file to the new location 
            string destPath = destination + @"\" + newFileName;

            var fi = new FileInfo(fsea.FullPath);


            // TODO Check if the file exist. 
            if (File.Exists(Path.Combine(Source, fsea.Name)))
            {

                // Check if the file is accessiable.
                if (IsAccessible(fi, FileMode.Open, FileAccess.Read))
                {
                    if (!File.Exists(destPath))
                    {
                        try
                        {
                            // Copy the file.
                            //File.Copy(fsea.FullPath, destPath);
                            // Move the file.
                            //File.Move(fsea.FullPath, destPath);
                            File.Copy(fsea.FullPath, destPath);

                            File.SetAttributes(destPath, FileAttributes.ReadOnly);


                            //Stopwatch sWatch = Stopwatch.StartNew();
                            //TimeSpan fileDropTimeout = new TimeSpan(0, 0, 10);
                            //bool fileActionSuccess = false;
                            //do
                            //{
                            //    // Copy the file.
                            //    //File.Copy(fsea.FullPath, destPath);
                            //    // Move the file.
                            //    //File.Move(fsea.FullPath, destPath);
                            //     File.Copy(fsea.FullPath, destPath);

                            //    File.SetAttributes(destPath, FileAttributes.ReadOnly);
                            //    fileActionSuccess = true;

                            //} while (sWatch.Elapsed < fileDropTimeout);

                            //if(!fileActionSuccess)
                            //{
                            //    Trace.WriteLine("File Move or File Attribute settings failed.");
                            //    throw new Exception();
                            //}

                            // Wait before checking for the file exists at destination.
                            Thread.Sleep(Convert.ToInt32(ConfigurationManager.AppSettings["ExistsAtDestination"]));
                            // Check if the file has actually been moved to dest.
                            if (!File.Exists(destPath))
                            {
                                // TODO Raise alarms here.
                                Trace.WriteLine("Failed to Move. File does not exist in destination. Setting ISS Fault Alarm bit");

                                //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                                // Notify HMI about the error type.
                                Trace.WriteLine("Failed to Move. File does not exist in destination.  Setting ISS File Move Fault Alarm bit");
                            }
                        }
                        catch (Exception ex)
                        {
                            // TODO log the exception and Raise alarm?
                            Trace.WriteLine("Failed to Move or set attributes on file. Setting ISS Fault Alarm bit");


                            //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                            // Notify HMI about the error type.
                            Trace.WriteLine("Failed to Move or set attributes on file. Setting ISS File Move Fault Alarm bit");
                        }

                    }
                    else
                    {
                        Trace.WriteLine("File Move failed as the file: " + newFileName + " already exists in the destination folder");
                    }
                }
                else
                {
                    Trace.WriteLine("File Move failed. File is not accessible");
                }
            }
        }

        /// <summary>
        /// Event which is raised when a file is created in the folder which is being watched.
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event arguments</param>
        private void fsw_Created(object sender, FileSystemEventArgs e)
        {
            lock (fswLock)
            {
                eventCount++;
                // Start the background worker.
                // Check whether if the background worker is busy if not continue.
                if (!bgWorker.IsBusy)
                {
                    bgWorker.RunWorkerAsync(e);
                }
                else
                {
                    Trace.WriteLine("An attempt to use background worker for concurrent tasks has been encountered ");
                    // Worker thread is busy.
                    int busyCount = 0;
                    while (busyCount < 4)
                    {
                        // Wait for 500ms and try again.
                        Thread.Sleep(500);
                        if (!bgWorker.IsBusy)
                        {
                            bgWorker.RunWorkerAsync(e);
                            break;
                        }
                        else
                        {
                            Trace.WriteLine("An attempt to use background worker for concurrent tasks has been encountered, attempt " + busyCount);
                            busyCount++;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Extension method to check if a file is accessible.
        /// </summary>
        /// <param name="fi">File Info</param>
        /// <param name="mode">File Mode</param>
        /// <param name="access">File Access</param>
        /// <returns>Attempts three times. True if the file is accessible</returns>
        private bool IsAccessible(FileInfo fi, FileMode mode, FileAccess access)
        {
            bool hasAccess = false;
            int i = 0;
            while (!hasAccess)
            {
                try
                {
                    using (var fileStream = File.Open(fi.FullName, mode, access))
                    {

                    }

                    hasAccess = true;

                    i = 1;
                    break;
                }
                catch (Exception ex)
                {

                    if (i < 4)
                    {
                        // We will swallow the exception, wait and try again.
                        Thread.Sleep(500);
                        // Explicitly set hasaccess flag.
                        hasAccess = false;
                        i++;
                    }
                    else
                    {
                        i = 0;
                        Trace.WriteLine("Failed to Move. File is not accessable. " + ex.ToString());
                        // Notify HMI
                        Trace.WriteLine("Failed to Move. File is not accessable.. Setting ISS Fault Alarm bit");


                        //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                        // Notify HMI about the error type.
                        Trace.WriteLine("Failed to Move. File is not accessable.. Setting ISS File Move Fault Alarm bit");
                        //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFileCopyFault);
                        // Explicitly set hasaccess flag.
                        hasAccess = false;
                        break;
                    }
                }
            }

            // return hasAccess;
            return true;
        }
        #endregion

    }

这些是我的发现,最终似乎可以移动文件而不丢失任何文件

后台工作人员不是正确的使用对象 为每个文件创建一个任务,让它完成自己的任务

更新后的watcher类如下所示

public sealed class Watcher
    {
        int eventCount = 0;

        #region Private Members
        /// <summary>
        /// File system watcher variable.
        /// </summary>
        private FileSystemWatcher fsw = null;
        /// <summary>
        /// Destination path to use.
        /// </summary>
        private string destination = @"c:\temp\doc2\";
        /// <summary>
        /// Source path to monitor.
        /// </summary>
        private string source = @"c:\temp\doc\";
        /// <summary>
        /// Default filter type is all files.
        /// </summary>
        private string filter = "*.bmp";
        /// <summary>
        /// Monitor all sub directories in the source folder.
        /// </summary>
        private bool includeSubdirectories = true;
        /// <summary>
        /// Background worker which will Move files.
        /// </summary>
        private BackgroundWorker bgWorker = null;
        /// <summary>
        /// Toggle flag to enable copying files and vice versa.
        /// </summary>
        private bool enableCopyingFiles = false;
        /// <summary>
        /// File System watcher lock.
        /// </summary>
        private object fswLock = new object();

        private static Watcher watcherInstance;
        #endregion

        #region Public Properties
        public static Watcher WatcherInstance
        {
            get
            {
                if (watcherInstance == null)
                {
                    watcherInstance = new Watcher();
                }
                return watcherInstance;
            }
        }



        public string Source
        {
            get
            {
                return source;
            }
            set
            {
                source = value;
            }
        }

        public string Destination
        {
            get
            {
                return destination;
            }
            set
            {
                destination = value;
            }
        }

        public string Filter
        {
            get
            {
                return filter;
            }
            set
            {
                filter = value;
            }
        }

        public bool MonitorSubDirectories
        {
            get
            {
                return includeSubdirectories;
            }
            set
            {
                includeSubdirectories = value;
            }
        }

        public bool EnableCopyingFiles
        {
            get
            {
                return enableCopyingFiles;
            }
            set
            {
                enableCopyingFiles = value;
            }
        }

        public FileSystemWatcher FSW
        {
            get
            {
                return fsw;
            }
            set
            {
                fsw = value;
            }
        }
        #endregion

        #region Construction
        /// <summary>
        /// Constructor.
        /// </summary>
        public Watcher()
        {
            // Intentionally left blank.

        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Method which will initialise the required 
        /// file system watcher objects to starting watching.
        /// </summary>
        public void InitialiseFSW()
        {
            fsw = new FileSystemWatcher();
            bgWorker = new BackgroundWorker();
        }

        /// <summary>
        /// Method which will start watching.
        /// </summary>
        public void StartWatch()
        {
            if (fsw != null)
            {
                fsw.Path = source;
                fsw.Filter = filter;
                fsw.IncludeSubdirectories = includeSubdirectories;
                fsw.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastAccess;

                // Setup events.
                fsw.Created += fsw_Created;
                // Important to set the below otherwise no events will be raised.
                fsw.EnableRaisingEvents = enableCopyingFiles;
                bgWorker.DoWork += bgWorker_DoWork;
            }
            else
            {
                Trace.WriteLine("File System Watcher is not initialised. Setting ISS Fault Alarm Bit");
                //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
            }
        }

        /// <summary>
        /// Method to stop watch.
        /// </summary>
        public void StopWatch()
        {
            // Stop Watcher.
            if (bgWorker != null)
            {
                bgWorker.DoWork -= bgWorker_DoWork;
            }
            if (fsw != null)
            {
                fsw.Created -= fsw_Created;
            }
        }
        #endregion


        #region Private Methods
        /// <summary>
        /// Method which will do the work on the background thread.
        /// Currently Move files from source to destination and 
        /// monitor disk capacity.
        /// </summary>
        /// <param name="sender">Object Sender</param>
        /// <param name="e">Event Arguments</param>
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {

        }

        private void PerformFileActions(string sourcePath)
        {
            string extractedFileName = Path.GetFileName(sourcePath);
            string newFileName = string.Empty;

            newFileName = "BatchCode" + "_" + extractedFileName;

            // We should now have the fully formed filename now. 
            // Move the file to the new location 
            string destPath = destination + @"\" + newFileName;

            var fi = new FileInfo(sourcePath);


            // TODO Check if the file exist. 
            if (File.Exists(Path.Combine(Source, extractedFileName)))
            {

                // Check if the file is accessiable.
                if (IsAccessible(fi, FileMode.Open, FileAccess.Read))
                {
                    if (!File.Exists(destPath))
                    {
                        try
                        {
                            File.Copy(sourcePath, destPath);
                            File.SetAttributes(destPath, FileAttributes.ReadOnly);

                            // Wait before checking for the file exists at destination.
                            Thread.Sleep(Convert.ToInt32(ConfigurationManager.AppSettings["ExistsAtDestination"]));
                            // Check if the file has actually been moved to dest.
                            if (!File.Exists(destPath))
                            {
                                // TODO Raise alarms here.
                                Trace.WriteLine("Failed to Move. File does not exist in destination. Setting ISS Fault Alarm bit");

                                //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                                // Notify HMI about the error type.
                                Trace.WriteLine("Failed to Move. File does not exist in destination.  Setting ISS File Move Fault Alarm bit");
                            }
                        }
                        catch (Exception ex)
                        {
                            // TODO log the exception and Raise alarm?
                            Trace.WriteLine("Failed to Move or set attributes on file. Setting ISS Fault Alarm bit");


                            //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                            // Notify HMI about the error type.
                            Trace.WriteLine("Failed to Move or set attributes on file. Setting ISS File Move Fault Alarm bit");
                        }

                    }
                    else
                    {
                        Trace.WriteLine("File Move failed as the file: " + newFileName + " already exists in the destination folder");
                    }
                }
                else
                {
                    Trace.WriteLine("File Move failed. File is not accessible");
                }
            }
        }

        /// <summary>
        /// Event which is raised when a file is created in the folder which is being watched.
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event arguments</param>
        private void fsw_Created(object sender, FileSystemEventArgs e)
        {
            lock (fswLock)
            {
                DateTime lastRead = DateTime.MinValue;

                DateTime lastWriteTime = File.GetCreationTime(e.FullPath);
                if (lastWriteTime != lastRead)
                {
                    eventCount++;

                    // Start a new task and forget.
                    Task.Factory.StartNew(() => {
                        PerformFileActions(e.FullPath);
                    });

                    lastRead = lastWriteTime;
                }

            }
        }

        /// <summary>
        /// Extension method to check if a file is accessible.
        /// </summary>
        /// <param name="fi">File Info</param>
        /// <param name="mode">File Mode</param>
        /// <param name="access">File Access</param>
        /// <returns>Attempts three times. True if the file is accessible</returns>
        private bool IsAccessible(FileInfo fi, FileMode mode, FileAccess access)
        {
            bool hasAccess = false;
            int i = 0;
            while (!hasAccess)
            {
                try
                {
                    using (var fileStream = File.Open(fi.FullName, mode, access))
                    {

                    }

                    hasAccess = true;

                    i = 1;
                    break;
                }
                catch (Exception ex)
                {

                    if (i < 4)
                    {
                        // We will swallow the exception, wait and try again.
                        Thread.Sleep(500);
                        // Explicitly set hasaccess flag.
                        hasAccess = false;
                        i++;
                    }
                    else
                    {
                        i = 0;
                        Trace.WriteLine("Failed to Move. File is not accessable. " + ex.ToString());
                        // Notify HMI
                        Trace.WriteLine("Failed to Move. File is not accessable.. Setting ISS Fault Alarm bit");


                        //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                        // Notify HMI about the error type.
                        Trace.WriteLine("Failed to Move. File is not accessable.. Setting ISS File Move Fault Alarm bit");
                        //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFileCopyFault);
                        // Explicitly set hasaccess flag.
                        hasAccess = false;
                        break;
                    }
                }
            }

            // return hasAccess;
            return true;
        }
        #endregion

    }
公共密封类监视程序
{
int eventCount=0;
#区域私人成员
/// 
///文件系统监视程序变量。
/// 
私有文件系统监视程序fsw=null;
/// 
///要使用的目标路径。
/// 
私有字符串目标=@“c:\temp\doc2\”;
/// 
///要监视的源路径。
/// 
私有字符串源=@“c:\temp\doc\”;
/// 
///默认过滤器类型为“所有文件”。
/// 
私有字符串筛选器=“*.bmp”;
/// 
///监视源文件夹中的所有子目录。
/// 
私有bool includeSubdirectories=true;
/// 
///将移动文件的后台工作程序。
/// 
私有BackgroundWorker bgWorker=null;
/// 
///切换标志以启用复制文件,反之亦然。
/// 
private bool enableCopyingFiles=false;
/// 
///文件系统监视程序锁。
/// 
私有对象fswLock=新对象();
私人静态观察者观察站;
#端区
#区域公共财产
公共静态观察程序
{
收到
{
if(watcherInstance==null)
{
watcherInstance=新的观察者();
}
返回观察站;
}
}
公共字符串源
{
收到
{
返回源;
}
设置
{
来源=价值;
}
}
公共字符串目的地
{
收到
{
返回目的地;
}
设置
{
目的地=价值;
}
}
公共字符串过滤器
{
收到
{
回流过滤器;
}
设置
{
过滤器=值;
}
}
公共布尔监视器子目录
{
收到
{
返回includeSubdirectories;
}
设置
{
includeSubdirectories=值;
}
}
公共bool启用copyingfiles
{
收到
{
返回enableCopyingFiles;
}
设置
{
enableCopyingFiles=值;
}
}
公共文件系统监视程序FSW
{
收到
{
返回fsw;
}
设置
{
fsw=值;
}
}
#端区
#区域建设
/// 
///构造器。
/// 
公众观察者()
{
//故意留下空白。
}
#端区
#区域公共方法
/// 
///方法,该方法将初始化所需的
///文件系统监视程序对象以开始监视。
/// 
public void InitialiseFSW()
{
fsw=newfilesystemwatcher();
bgWorker=新的BackgroundWorker();
}
/// 
///方法,该方法将开始监视。
/// 
公共无效StartWatch()
{
如果(fsw!=null)
{
路径=源;
fsw.Filter=过滤器;
fsw.IncludeSubdirectories=IncludeSubdirectories;
fsw.NotifyFilter=NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastAccess;
//设置事件。
fsw.Created+=fsw_Created;
//请务必设置以下选项,否则不会引发任何事件。
fsw.EnableRaisingEvents=启用复制文件;
bgWorker.DoWork+=bgWorker\u DoWork;
}
其他的
{
Trace.WriteLine(“文件系统监视程序未初始化。设置ISS故障报警位”);
//CommonActions.SetAlarmBit(ApplicationConstants.tag\u AlarmTag,ApplicationConstants.bit\u ISSFault);
}
}
/// 
///方法停止监视。
/// 
公众免费秒表()
{
//停止观察者。
if(bgWorker!=null)
{
bgWorker.DoWork-=bgWorker\u DoWork;
}
如果(fsw!=null)
{
fsw.Created-=fsw_Created;
}
}
#端区
#区域私有方法
/// 
///方法,该方法将在后台线程上执行工作。
///当前将文件从源移动到目标和
///监视磁盘容量。
/// 
///对象发送器
///事件参数
私有void bgWorker\u DoWork(对象发送方,DoWorkEventArgs e)
{
}
私人无效行为文件(strin)
public sealed class Watcher
    {
        int eventCount = 0;

        #region Private Members
        /// <summary>
        /// File system watcher variable.
        /// </summary>
        private FileSystemWatcher fsw = null;
        /// <summary>
        /// Destination path to use.
        /// </summary>
        private string destination = @"c:\temp\doc2\";
        /// <summary>
        /// Source path to monitor.
        /// </summary>
        private string source = @"c:\temp\doc\";
        /// <summary>
        /// Default filter type is all files.
        /// </summary>
        private string filter = "*.bmp";
        /// <summary>
        /// Monitor all sub directories in the source folder.
        /// </summary>
        private bool includeSubdirectories = true;
        /// <summary>
        /// Background worker which will Move files.
        /// </summary>
        private BackgroundWorker bgWorker = null;
        /// <summary>
        /// Toggle flag to enable copying files and vice versa.
        /// </summary>
        private bool enableCopyingFiles = false;
        /// <summary>
        /// File System watcher lock.
        /// </summary>
        private object fswLock = new object();

        private static Watcher watcherInstance;
        #endregion

        #region Public Properties
        public static Watcher WatcherInstance
        {
            get
            {
                if (watcherInstance == null)
                {
                    watcherInstance = new Watcher();
                }
                return watcherInstance;
            }
        }



        public string Source
        {
            get
            {
                return source;
            }
            set
            {
                source = value;
            }
        }

        public string Destination
        {
            get
            {
                return destination;
            }
            set
            {
                destination = value;
            }
        }

        public string Filter
        {
            get
            {
                return filter;
            }
            set
            {
                filter = value;
            }
        }

        public bool MonitorSubDirectories
        {
            get
            {
                return includeSubdirectories;
            }
            set
            {
                includeSubdirectories = value;
            }
        }

        public bool EnableCopyingFiles
        {
            get
            {
                return enableCopyingFiles;
            }
            set
            {
                enableCopyingFiles = value;
            }
        }

        public FileSystemWatcher FSW
        {
            get
            {
                return fsw;
            }
            set
            {
                fsw = value;
            }
        }
        #endregion

        #region Construction
        /// <summary>
        /// Constructor.
        /// </summary>
        public Watcher()
        {
            // Intentionally left blank.

        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Method which will initialise the required 
        /// file system watcher objects to starting watching.
        /// </summary>
        public void InitialiseFSW()
        {
            fsw = new FileSystemWatcher();
            bgWorker = new BackgroundWorker();
        }

        /// <summary>
        /// Method which will start watching.
        /// </summary>
        public void StartWatch()
        {
            if (fsw != null)
            {
                fsw.Path = source;
                fsw.Filter = filter;
                fsw.IncludeSubdirectories = includeSubdirectories;
                fsw.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastAccess;

                // Setup events.
                fsw.Created += fsw_Created;
                // Important to set the below otherwise no events will be raised.
                fsw.EnableRaisingEvents = enableCopyingFiles;
                bgWorker.DoWork += bgWorker_DoWork;
            }
            else
            {
                Trace.WriteLine("File System Watcher is not initialised. Setting ISS Fault Alarm Bit");
                //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
            }
        }

        /// <summary>
        /// Method to stop watch.
        /// </summary>
        public void StopWatch()
        {
            // Stop Watcher.
            if (bgWorker != null)
            {
                bgWorker.DoWork -= bgWorker_DoWork;
            }
            if (fsw != null)
            {
                fsw.Created -= fsw_Created;
            }
        }
        #endregion


        #region Private Methods
        /// <summary>
        /// Method which will do the work on the background thread.
        /// Currently Move files from source to destination and 
        /// monitor disk capacity.
        /// </summary>
        /// <param name="sender">Object Sender</param>
        /// <param name="e">Event Arguments</param>
        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {

        }

        private void PerformFileActions(string sourcePath)
        {
            string extractedFileName = Path.GetFileName(sourcePath);
            string newFileName = string.Empty;

            newFileName = "BatchCode" + "_" + extractedFileName;

            // We should now have the fully formed filename now. 
            // Move the file to the new location 
            string destPath = destination + @"\" + newFileName;

            var fi = new FileInfo(sourcePath);


            // TODO Check if the file exist. 
            if (File.Exists(Path.Combine(Source, extractedFileName)))
            {

                // Check if the file is accessiable.
                if (IsAccessible(fi, FileMode.Open, FileAccess.Read))
                {
                    if (!File.Exists(destPath))
                    {
                        try
                        {
                            File.Copy(sourcePath, destPath);
                            File.SetAttributes(destPath, FileAttributes.ReadOnly);

                            // Wait before checking for the file exists at destination.
                            Thread.Sleep(Convert.ToInt32(ConfigurationManager.AppSettings["ExistsAtDestination"]));
                            // Check if the file has actually been moved to dest.
                            if (!File.Exists(destPath))
                            {
                                // TODO Raise alarms here.
                                Trace.WriteLine("Failed to Move. File does not exist in destination. Setting ISS Fault Alarm bit");

                                //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                                // Notify HMI about the error type.
                                Trace.WriteLine("Failed to Move. File does not exist in destination.  Setting ISS File Move Fault Alarm bit");
                            }
                        }
                        catch (Exception ex)
                        {
                            // TODO log the exception and Raise alarm?
                            Trace.WriteLine("Failed to Move or set attributes on file. Setting ISS Fault Alarm bit");


                            //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                            // Notify HMI about the error type.
                            Trace.WriteLine("Failed to Move or set attributes on file. Setting ISS File Move Fault Alarm bit");
                        }

                    }
                    else
                    {
                        Trace.WriteLine("File Move failed as the file: " + newFileName + " already exists in the destination folder");
                    }
                }
                else
                {
                    Trace.WriteLine("File Move failed. File is not accessible");
                }
            }
        }

        /// <summary>
        /// Event which is raised when a file is created in the folder which is being watched.
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event arguments</param>
        private void fsw_Created(object sender, FileSystemEventArgs e)
        {
            lock (fswLock)
            {
                DateTime lastRead = DateTime.MinValue;

                DateTime lastWriteTime = File.GetCreationTime(e.FullPath);
                if (lastWriteTime != lastRead)
                {
                    eventCount++;

                    // Start a new task and forget.
                    Task.Factory.StartNew(() => {
                        PerformFileActions(e.FullPath);
                    });

                    lastRead = lastWriteTime;
                }

            }
        }

        /// <summary>
        /// Extension method to check if a file is accessible.
        /// </summary>
        /// <param name="fi">File Info</param>
        /// <param name="mode">File Mode</param>
        /// <param name="access">File Access</param>
        /// <returns>Attempts three times. True if the file is accessible</returns>
        private bool IsAccessible(FileInfo fi, FileMode mode, FileAccess access)
        {
            bool hasAccess = false;
            int i = 0;
            while (!hasAccess)
            {
                try
                {
                    using (var fileStream = File.Open(fi.FullName, mode, access))
                    {

                    }

                    hasAccess = true;

                    i = 1;
                    break;
                }
                catch (Exception ex)
                {

                    if (i < 4)
                    {
                        // We will swallow the exception, wait and try again.
                        Thread.Sleep(500);
                        // Explicitly set hasaccess flag.
                        hasAccess = false;
                        i++;
                    }
                    else
                    {
                        i = 0;
                        Trace.WriteLine("Failed to Move. File is not accessable. " + ex.ToString());
                        // Notify HMI
                        Trace.WriteLine("Failed to Move. File is not accessable.. Setting ISS Fault Alarm bit");


                        //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFault);
                        // Notify HMI about the error type.
                        Trace.WriteLine("Failed to Move. File is not accessable.. Setting ISS File Move Fault Alarm bit");
                        //CommonActions.SetAlarmBit(ApplicationConstants.tag_AlarmTag, ApplicationConstants.bit_ISSFileCopyFault);
                        // Explicitly set hasaccess flag.
                        hasAccess = false;
                        break;
                    }
                }
            }

            // return hasAccess;
            return true;
        }
        #endregion

    }