特定のマスクに適合するファイルを検索する関数を作ってみましょう。ファイルの検索には二通りあります。一つはワイルドカードで全てのファイルを検索するようにして、発見したファイルの拡張子がマスクに適合するかどうかを判定するタイプ。もう一つは拡張子毎に検索をかける方法です。トータルで見ると前者よりも後者の方がパフォーマンスが高いので、ここでは後者の方法を選択して関数を作成します。
サブディレクトリ内のファイル検索にも対応します。マスク検索関数内にディレクトリを再帰的に検索する関数を作り、予めディレクトリリストを作成してからファイルの検索を開始するようにします。(その方が簡単だから(^^;)
procedure FindFile(RootDir, FileMask: String; FindAttr: Integer;
FindSubDir: Boolean; Files: TStrings);
{
Path :検索を行うディレクトリ(終端は「\」でなくても構いません)
FileMask :マスクを指定します。複数のマスクを指定する場合はセミコロンで区切ります。
全てのファイルを検索する場合は「*」または「*.*」を指定してください。
FindAttr :検索するファイルの属性です。
FindSubDir:サブディレクトリも検索する場合はTrue
Files :検索されたファイルを格納する文字列リストオブジェクト
}
//ディレクトリを再起検索する関数内関数
procedure _LocalFindDirectory(Dir: String; Directorys: TStrings);
var
F: TSearchRec;
Success: Boolean;
begin
Success := FindFirst(Dir+'*.*', faDirectory, F) = 0;
if Success then
begin
try
while Success do
begin
if (F.Name <> '.') and (F.Name <> '..') and
((F.Attr and faDirectory) > 0) then
begin
Directorys.Add(Dir + F.Name + '\');
_LocalFindDirectory(Dir + F.Name + '\', Directorys);
end;
Success := FindNext(F) = 0;
end;
finally
FindClose(F);
end;
end;
end;
var
Extention, Dirctorys: TStringList;
i, j: Integer;
F: TSearchRec;
Success: Boolean;
DirBuf: String;
begin
Files.BeginUpdate;
Files.Clear;
Extention := TStringList.Create;
Dirctorys := TStringList.Create;
try
//拡張子の二重登録は禁止する
Extention.Duplicates := dupIgnore;
//セミコロンで区切られたマスクを文字列リストに変換する
Extention.Text := AnsiLowerCase(StringReplace(FileMask, ';',
#13#10, [rfReplaceAll]));
//*.*が含まれている場合は全てのファイルを検索
with Extention do
if (IndexOf('*.*') <> -1) or (IndexOf('*') <> -1) then
Text := '*.*';
//検索ディレクトリの終端に「\」記号がなければ追加する
RootDir := IncludeTrailingBackslash(RootDir);
Dirctorys.Add(RootDir);
//ファイルを検索するディレクトリを取得する
if FindSubDir then
_LocalFindDirectory(RootDir, Dirctorys);
//ファイルを検索する
for i := 0 to Dirctorys.Count -1 do
begin
DirBuf := Dirctorys[i];
{ 一つのディレクトリに対してマスクの数だけ検索をする }
for j := 0 to Extention.Count -1 do
begin
Success := FindFirst(DirBuf + Extention[j], FindAttr, F) = 0;
if Success then
begin
try
while Success do
begin
if (F.Name <> '.') and (F.Name <> '..') and
((F.Attr and faDirectory) = 0) then
Files.Add(DirBuf + F.Name);
Success := FindNext(F) = 0;
end
finally
FindClose(F);
end;
end;
end;
end;
finally
//後始末
Files.EndUpdate;
Extention.Free;
Dirctorys.Free;
end;
end;
|