[.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)
{
// 檔案建立後要做的事
}
}
}
}
簽名檔
期許自己能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。