フォルダ、ファイルの変更を監視する

System.IO.FileSystemWatcherクラスを使って、フォルダやファイルが変更されたら、すぐにわかる方法を紹介します。

 インタラクティブシェルを使いながら、動作を試す

 今回はインタラクティブシェルを使って、SystemWatcherクラスを試しながら説明していきます。
 >>> import System
 >>> from System.IO import FileSystemWatcher
 >>> watch = FileSystemWatcher()
 まずFileSystemWatcherクラスのオブジェクトを作ります。
 >>> watch.Path = 'c:\\test'
 >>> watch.Filter = '*.txt';
 >>> watch.IncludeSubdirectories = False
 次にオブジェクトのプロパティを設定します。

 Pathプロパティ:監視するディレクトリのパスを指定します。
 Filterプロパティ:監視するファイルの拡張子を指定します。
 IncludeSubdirectoriesプロパティ:
           サブディレクトリを監視するかどうかを指定します。
 >>> from System.IO.NotifyFilters import FileName, DirectoryName, LastWrite
 >>> watch.NotifyFilter = FileName | DirectoryName | LastWrite
 次にどんな種類の変更を監視するか指定します。監視できる変更は次のものがあります。
Attributes ファイルまたはフォルダの属性。
CreationTime ファイルまたはフォルダが作成された時刻。
DirectoryName ディレクトリ名。
FileName ファイルの名前。
LastAccess ファイルまたはフォルダを最後に開いた日付。
LastWrite ファイルまたはフォルダへの最終書き込み日付。
Security ファイルまたはフォルダのセキュリティ設定。
Size ファイルまたはフォルダのサイズ。
 >>> from System.IO.WatcherChangeTypes import All
 >>> changedResult = watch.WaitForChanged(All,60000)
 監視を実行します。今回はすべての変更に対して監視を実施し、監視は1分間
(60000ミリ秒)行います。 1分間ほったらかしにしておきます。入力ができるようになったら次のことを確認してみましょう。
 >>> changedResult.TimedOut
 True
 >>> print changedResult.ChangeType
 0
 何も変更がなかったら、TimedOutプロパティがTrueになることと、ChangeTypeプロパティが"0"になることがわかりました。
 >>> from System.IO.WatcherChangeTypes import Created, Changed, Renamed, Deleted
 ChangeTypeプロパティには作成(Created)、変更(Changed)、名前変更(Renamed)、削除(Deleted)の4つがあります。それぞれの動作を見ていきましょう。

 >>> changedResult = watch.WaitForChanged(All,60000)
 >>> print changedResult.ChangeType
 Created
 >>> print changedResult.Name
 temp.txt
 監視を実行した後に、対象になっているディレクトリに"temp.txt"ファイルを作成してみます。すると入力できるようになり上記の結果になります。
 >>> changedResult = watch.WaitForChanged(All,60000)
 >>> print changedResult.ChangeType
 Changed
 >>> print changedResult.Name
 temp.txt
 次に監視を実行した後に、"temp.txt"ファイルの内容を変更してみましょう。すると入力できるようになり上記の結果になります。
 >>> changedResult = watch.WaitForChanged(All,60000)
 >>> print changedResult.ChangeType
 Renamed
 >>> print changedResult.Name
 test.txt
 >>> print changedResult.OldName
 temp.txt
 次に監視を実行した後に、"temp.txt"ファイルのファイル名を"test.txt"に変更してみましょう。すると入力できるようになり上記の結果になります。
 >>> changedResult = watch.WaitForChanged(All,60000)
 >>> print changedResult.ChangeType
 Deleted
 >>> print changedResult.Name
 test.txt
 最後に監視を実行した後に、"test.txt"ファイルを"test.txt"を削除してみてください。すると入力できるようになり上記の結果になります。

 スクリプトファイルにしてみる

 今までやってきたことを踏まえてスクリプトにして見ます。

import System
from System.IO import FileSystemWatcher

watch = FileSystemWatcher()
watch.Path = 'c:\\test'
watch.Filter = '*.txt';

from System.IO.NotifyFilters import FileName, DirectoryName, LastWrite
watch.NotifyFilter = FileName | DirectoryName | LastWrite
watch.IncludeSubdirectories = False

from System.IO.WatcherChangeTypes import All
print '監視を開始します。'

changedResult = watch.WaitForChanged(All,60000)

if changedResult.TimedOut :
  print "1分間にFile変更はありません"

from System.IO.WatcherChangeTypes import Changed, Created, Deleted, Renamed

if changedResult.ChangeType == Created :
  print '"'+ changedResult.Name.ToString() + '"が作成されました。'

if changedResult.ChangeType == Changed :
  print '"'+ changedResult.Name.ToString() + '"が変更されました。'

if changedResult.ChangeType == Renamed :
  print ('"'+ changedResult.OldName.ToString() + '"から"'
    + changedResult.Name.ToString() + '"へFile名が変更されました。')
     ↑カッコの中では,改行や空白を使うことが出来ます。
     ↑コードをきれいに書くためのテクニック!!

if changedResult.ChangeType == Deleted :
  print '"'+ changedResult.Name.ToString() + '"が削除されました。'

raw_input()

出力画面例
 監視を開始します。
 1分間にFile変更はありません
 実はこのようなことを、このサイトを作りながら私がいつもやっています。