개발팁2019. 3. 19. 14:42

[C#] 파일시스템의 폴더감시 FileSystemWatcher

 

System.IO.FileSystemWatcher

 

System.IO 에 속한, FileSystemWatcher 를 이용하면, 폴더내의 파일시스템의 변화를 감지할 수 있다.

 

여기서 말하는 파일 시스템은, 파일과 폴더를 모두 포함한다.

 

감지할 수 있는 이벤트는

 

Changed - 파일이나 폴더의 변경
Created - 파일이나 폴더의 생성
Deleted - 파일이나 폴더의 삭제
Renamed - 파일이나 폴더의 이름 변경

 


실제 코드는 아래와 같이 구성하면 된다.

 

 

private void Run_Watcher()
{
 this.m_FolderWatcher = new FileSystemWatcher();

 this.m_FolderWatcher.Filter = "*.*";
 this.m_FolderWatcher.Path = "C:\\Program Files\\";
 this.m_FolderWatcher.IncludeSubdirectories = true;

 this.m_FolderWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
 this.m_FolderWatcher.Changed += new FileSystemEventHandler(Watcher_OnChanged);
 this.m_FolderWatcher.Created += new FileSystemEventHandler(Watcher_OnChanged);
 this.m_FolderWatcher.Deleted += new FileSystemEventHandler(Watcher_OnChanged);
 this.m_FolderWatcher.Renamed += new RenamedEventHandler(Watcher_OnRenamed);
 this.m_FolderWatcher.EnableRaisingEvents = true;
}

 

private void Watcher_OnChanged(object sender, FileSystemEventArgs e)
{
 Console.WriteLine(string.Format("{0} {1}", e.FullPath, e.ChangeType.ToString()));
}

 

private void Watcher_OnRenamed(object sender, RenamedEventArgs e)
{
 Console.WriteLine(string.Format("{0} {1} to {2}", e.OldFullPath, e.ChangeType.ToString(), e.Name));
}

 

 

 

Filter 라는것은, 지정된 경로(Path) 아래에서도, 모든 파일(*.*) 을 다 감시 할지, 특정 파일(ex : *.txt) 만 감시할지를 지정하게 된다.

 

IncludeSubdirectories 는 경로(Path) 아래의 모든 하위폴더를 다 포함할지 여부이다.

 

NotifyFilter 는 파일이나 폴더의 변경형식을 선택할 수 있다.

 

다수의 형식을 선택하기 위해 bitwise or 연산자를 사용한다.

8가지중에 선택할 수 있다.

 

FileName = 1,
DirectoryName = 2,
Attributes = 4,
Size = 8,
LastWrite = 16,
LastAccess = 32,
CreationTime = 64,
Security = 256

 

 

Changed, Created, Deleted 는 모두 event 파라미터가 동일(FileSystemEventArgs) 하기 때문에, 하나의 이벤트 핸들러로 연결시켰다.
(각자 별도의 이벤트 핸들러를 만들어도 상관은 없다.)


FileSystemEventArgs 의 ChangeType 으로, 어떤 변화인지 찾아 낼 수 있다. (Created, Changed, Deleted, Renamed)

 

마지막으로,
EnableRaisingEvents = true

 

를 해줌으로써, 파일시스템의 감시가 활성화 된다.

 

감시를 중단하고 싶을때는,

EnableRaisingEvents = false

 

로 해주면 된다.

실제로, 특정 폴더를 감시하는 프로그램은 아래와 같이 나오게 된다.

 

 

 

 

한가지 팁으로,

 

특정 FTP 경로를 감시하고 있다가, FTP 로 업로드가 될 경우, 자동으로 배포 하는 프로그램을 만든다면,

어떤 이벤트를 사용해야 할까?

Created? Changed?

 

정답은 2개를 다 사용해야 한다.

 

우선, FTP 로 파일이 업로드 시작되면, Created 이벤트가 발생한다.

그리고, 파일이 업로드가 진행되면, Changed 가 발생하게 된다.

 

여기서 중요한것은 FTP로 파일 업로드가 종료된(파일이 모두 업로드된) 시점을 알아야 한다.

이를 위해, 파일을 Write 모드로 Open 해서, Open 이 된다면, 정상적으로 업로드가 완료된것으로 보면 된다.

 

 
private void Watcher_OnCreated(object sender, FileSystemEventArgs e)
{
 string ext = Path.GetExtension(e.FullPath);

 this.m_Wacher_CreatedFileName = e.FullPath;
}

 

private void Watcher_OnChanged(object sender, FileSystemEventArgs e)
{
 if (e.ChangeType != WatcherChangeTypes.Changed)
  return;

 if (this.m_Wacher_CreatedFileName != e.FullPath)
  return;

 

 // 쓰기모드로 오픈이 가능해야, 파일복사가 완료된것으로 본다.
 try
 {
  FileStream fs = File.Open(e.FullPath, FileMode.Open);
  fs.Close();
  fs.Dispose();
 }
 catch(IOException)
 {
  return;
 }
}

 

 

위 코드는 실제로 사용되는 코드이다.

 

 

Posted by 헝개