JclのTJclFileEnumeratorを使ってみる

TJclFileEnumeratorはディレクトリ中からファイルを検索する強力なクラスです。
検索オプションは豊富で、検索処理はスレッドで行われます。

TJclFileEnumeratorを使うにはJclFileUtilsユニットをusesに追加します。

uses JclFileUtils;

TJclFileEnumeratorには2つのイベントがあります。

OnEnterDirectoryイベントは、検索処理が新しいディレクトリに入ったときに発生するイベントです。
イベントはTFileHandler型で、ディレクトリの名前が引数になります。

TFileHandler = procedure (const FileName: string) of object;

OnTerminateTaskイベントは、検索処理が終了したときに発生するイベントです。
イベントはTFileSearchTerminationEvent型で、引数のTFileSearchTaskIDは処理が終わったタスクのID、引数Abortedは処理が中断されたときはTrueになります。

TFileSearchTerminationEvent = procedure (const ID: TFileSearchTaskID; const Aborted: Boolean) of object;

イベントを代入して設定します。

FFileEnumerator.OnEnterDirectory := DirectoryEntered;
FFileEnumerator.OnTerminateTask := TaskDone;

イベントの処理の例です。

{ Public 宣言 }
/// <summary>
///   検索処理が新しいディレクトリに入ったとき
/// </summary>
/// <param name="Directory">
///   ディレクトリ名
/// </param>
procedure DirectoryEntered(const Directory: string);

/// <summary>
///   検索処理が終了したとき
/// </summary>
/// <param name="ID">
///   処理が終わったタスクのID
/// </param>
/// <param name="Aborted">
///   処理が中断されたときはTrue
/// </param>
procedure TaskDone(const ID: TFileSearchTaskID; const Aborted: Boolean);

procedure TForm1.DirectoryEntered(const Directory: string);
begin
  //検索処理が新しいディレクトリに入ったときは、
  //ステータスバーにディレクトリ名を表示する
  StatusBar1.SimpleText := Format('Processing %s...', [Directory]);
end;

procedure TForm1.TaskDone(const ID: TFileSearchTaskID; const Aborted: Boolean);
begin
  //検索処理が終了したときは、開始ボタンを中止ボタンの状態を変更
  StartBtn.Enabled := True;
  StopBtn.Enabled := False;
end;

検索するファイルの条件を設定します。

//ファイルの更新日が指定日以降
FFileEnumerator.SearchOption[fsLastChangeAfter] := True;
FFileEnumerator.LastChangeAfter = EncodeDate(2012, 1, 1);

//ファイルの更新日が指定日以前
FFileEnumerator.SearchOption[fsLastChangeBefore] := True;
FFileEnumerator.LastChangeBefore = EncodeDate(2012, 7, 1);

//ファイルサイズの最小値
FFileEnumerator.SearchOption[fsMinSize] := True;
FFileEnumerator.FileSizeMin := 100;

//ファイルサイズの最大値
FFileEnumerator.SearchOption[fsMaxSize] := True;
FFileEnumerator.FileSizeMax := 9999;

//マスク
FFileEnumerator.FileMask := '*.pas;*.dfm;*.xfm;*.dpr;*.dpk*';

//サブディレクトリを検索するときはTrue
FFileEnumerator.IncludeSubDirectories := True;

//属性が「隠しファイル」のディレクトリを検索するときはTrue
FFileEnumerator.IncludeHiddenSubDirectories := True;

//マスクにマッチするファイル名の大文字と小文字を区別するときはTrue
FFileEnumerator.CaseSensitiveSearch := True;

//検索するディレクトリのルートディレクトリ
FFileEnumerator.RootDirectory := 'C:\lib';

//ルートディレクトリが複数の時はRootDirectoriesにTStringsを設定します。
FFileEnumerator.RootDirectories := Directories;

検索を実行するには、ForEachメソッドを実行します。
ForEachメソッドは2種類あり、引数の型が異なります。
返り値のTFileSearchTaskIDは処理を一意に識別する数値です。処理を中断するときに使用します。

function ForEach(Handler: TFileHandler): TFileSearchTaskID; overload;
function ForEach(Handler: TFileHandlerEx): TFileSearchTaskID; overload;

TFileHandler = procedure (const FileName: string) of object;
TFileHandlerEx = procedure (const Directory: string; const FileInfo: TSearchRec) of object;

どちらも、引数は見つかったファイルの情報になります。

/// <summary>
///   ファイルが見つかったとき
/// </summary>
/// <param name="Directory">
///   ディレクトリ名
/// </param>
/// <param name="FileInfo">
///   ファイルの情報<
/// </param>
procedure AddFile(const Directory: string; const FileInfo: TSearchRec);

procedure TForm1.AddFile(const Directory: string; const FileInfo: TSearchRec);
var
  ListItem: TListItem;
begin
  //検索条件にマッチしたファイルの情報をリストビューに表示する
  ListItem := ListView1.Items.Add;
  ListItem.Caption := Directory + FileInfo.Name;
  ListItem.SubItems.Add(IntToStr(FileInfo.Size));
end;

検索処理を実行します。

FTaskID := FFileEnumerator.ForEach(AddFile);

検索処理を中止するにはStopTaskメソッドを使用します。

procedure TFileSearchForm.StopBtnClick(Sender: TObject);
begin
  //中止ボタンが押されたときは検索処理を中止する
  FFileEnumerator.StopTask(FTaskID);
end;

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください