[.NET] 如何監看檔案建立完畢

[.NET] : 如何監看檔案建立完畢


前言 :

一般在監控資料夾或是檔案異動,大多使用FileSystemWatcher類別
但FileSystemWatcher在監控檔案建立的事件時
他發出的 Created事件的時間點,是在檔案建立開始的當時,而不是檔案建立完畢的時間點。
如果直接使用的話,有時會造成建立檔案的執行緒跟監控檔案的執行緒互相衝突
造成『由於另一個處理序正在使用檔案』的例外產生。


改為本篇文章介紹的使用方法及可避免上述問題


實作 :


using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 
 
namespace ConsoleApplication1 
{ 
    public class SampleFolderWatcher 
    { 
        // Properties  
        private string _folderPath = null; 
 
        private FileSystemWatcher _watcher = null; 
 
        private List<string> _creatingFiles = new List<string>(); 
 
 
        // Construction 
        public SampleFolderWatcher(string folderPath) 
        { 
            Require#region Require 
 
            if (folderPath == null) throw new ArgumentNullException(); 
 
            #endregion 
 
            _folderPath = folderPath; 
 
            _watcher = new FileSystemWatcher(); 
            _watcher.Path = _folderPath; 
            _watcher.Created += new FileSystemEventHandler(FileSystemWatcher_Creating); 
            _watcher.Changed += new FileSystemEventHandler(FileSystemWatcher_Changed); 
            _watcher.EnableRaisingEvents = true; 
        } 
 
 
        // FileSystemWatcher Events 
        private void FileSystemWatcher_Creating(object sender, FileSystemEventArgs e) 
        { 
            if (File.Exists(e.FullPath) == true) 
            { 
                if (_creatingFiles.Contains(e.FullPath) == true) 
                { 
                    _creatingFiles.Remove(e.FullPath); 
                } 
                _creatingFiles.Add(e.FullPath); 
            } 
        } 
 
        private void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e) 
        { 
            if (File.Exists(e.FullPath) == true) 
            { 
                if (_creatingFiles.Contains(e.FullPath) == true) 
                { 
                    try 
                    { 
                        FileStream stream = File.OpenWrite(e.FullPath); 
                        stream.Close(); 
 
                        _creatingFiles.Remove(e.FullPath); 
 
                        FileSystemWatcher_Created(sender, new FileSystemEventArgs(WatcherChangeTypes.Created, Path.GetDirectoryName(e.FullPath), Path.GetFileName(e.FullPath))); 
                    } 
                    catch 
                    { 
 
                    } 
                } 
            } 
        } 
 
        private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e) 
        { 
            if (File.Exists(e.FullPath) == true) 
            { 
                // 檔案建立後要做的事 
            } 
        } 
    } 
}
期許自己
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。