指定したフォルダ以下にあるファイルのうち、指定した文字列を含むファイルを探す方法を紹介します。
.NET Framework 2.0以降のVB.NETでは、My.Computer.FileSystem.FindInFilesメソッドにより、可能です。ただし、ファイルの文字コードはEncoding.Default(あるいは、StreamReaderクラスが判別できるエンコーディング)として扱われます。
下に示すコードでは、"C:\My Documents"フォルダ以下にあるすべてのHTMLファイル(拡張子が、".htm"または".html")から、「DOBON.NET」という文字列を含むファイルを大文字小文字を区別して検索しています。
'"DOBON.NET"を含むHTMLファイルを、大文字小文字を区別して探す Dim files As System.Collections.ObjectModel.ReadOnlyCollection(Of String) = _ My.Computer.FileSystem.FindInFiles( _ "C:\My Documents", _ "DOBON.NET", _ False, _ FileIO.SearchOption.SearchAllSubDirectories, _ New String() {"*.htm", "*.html"}) '結果を表示 For Each f As String In files Console.WriteLine(f) Next
//参照にMicrosoft.VisualBasic.dllを追加する必要がある //"DOBON.NET"を含むHTMLファイルを、大文字小文字を区別して探す System.Collections.ObjectModel.ReadOnlyCollection<string> files = Microsoft.VisualBasic.FileIO.FileSystem.FindInFiles( "C:\\My Documents", "DOBON.NET", false, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, new string[] {"*.htm", "*.html"}); //結果を表示 foreach (string f in files) { Console.WriteLine(f); }
My.Computer.FileSystem.FindInFilesメソッドが使えなかったり、Grep(正規表現を使用した検索)を行いたいときなどでは、自分でコードを書く必要があります。基本的には、DirectoryInfo.GetFilesで検索対象とするファイルを探し、ファイルの内容を読み込み、Regex.IsMatchで指定された正規表現パターンと一致するか調べるという流れになるでしょう。これらの方法については、以下のページで解説しています。
具体的な例を示します。ここでは、"C:\My Documents"フォルダにある拡張子が".html"のファイルの内、「DOBON.NET」という文字列が含まれているファイルを列挙しています。ごく簡単な例として参考にしてください。(ファイルを一度に読み込んでいますので、検索するファイルのサイズを制限するなどの対策が必要でしょう。)
'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles Button1.Click 'Grepの実行 Dim files As String() = _ Grep("C:\My Documents", "DOBON\.NET", "*.html", False) '結果の表示 Dim f As String For Each f In files Console.WriteLine(f) Next f End Sub ''' <summary> ''' Grepを行う ''' </summary> ''' <param name="dirPath">フォルダのパス。</param> ''' <param name="pattern">検索する正規表現のパターン。</param> ''' <param name="fileWildcards">対象とするファイル。</param> ''' <param name="ignoreCase">大文字小文字を区別するか。</param> ''' <returns>見つかったファイルパスの配列。</returns> Public Shared Function Grep(ByVal dirPath As String, _ ByVal pattern As String, ByVal fileWildcards As String, _ ByVal ignoreCase As Boolean) As String() Dim fileCol As New System.Collections.ArrayList() '正規表現のオプションを設定 Dim opts As System.Text.RegularExpressions.RegexOptions = _ System.Text.RegularExpressions.RegexOptions.None If ignoreCase Then opts = opts Or System.Text.RegularExpressions.RegexOptions.IgnoreCase End If Dim reg As New System.Text.RegularExpressions.Regex(pattern, opts) 'フォルダ内にあるファイルを取得 Dim dir As New System.IO.DirectoryInfo(dirPath) Dim files As System.IO.FileInfo() = dir.GetFiles(fileWildcards) Dim f As System.IO.FileInfo For Each f In files '一つずつファイルを調べる If ContainTextInFile(f.FullName, reg) Then fileCol.Add(f.FullName) End If Next f Return CType(fileCol.ToArray(GetType(String)), String()) End Function 'ファイルの内容がpatternに一致するか調べる Private Shared Function ContainTextInFile(ByVal filePath As String, _ ByVal reg As System.Text.RegularExpressions.Regex) As Boolean 'ファイルを読み込む Dim strm As System.IO.StreamReader = Nothing Dim txt As String = "" Try strm = New System.IO.StreamReader( _ filePath, System.Text.Encoding.Default, True) txt = strm.ReadToEnd() Finally strm.Close() End Try Return reg.IsMatch(txt) End Function
//Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { //Grepの実行 string[] files = Grep("C:\\My Documents", "DOBON\\.NET", "*.html", false); //結果の表示 foreach (string f in files) { Console.WriteLine(f); } } /// <summary> /// Grepを行う /// </summary> /// <param name="dirPath">フォルダのパス。</param> /// <param name="pattern">検索する正規表現のパターン。</param> /// <param name="fileWildcards">対象とするファイル。</param> /// <param name="ignoreCase">大文字小文字を区別するか。</param> /// <returns>見つかったファイルパスの配列。</returns> public static string[] Grep( string dirPath, string pattern, string fileWildcards, bool ignoreCase) { System.Collections.ArrayList fileCol = new System.Collections.ArrayList(); //正規表現のオプションを設定 System.Text.RegularExpressions.RegexOptions opts = System.Text.RegularExpressions.RegexOptions.None; if (ignoreCase) opts |= System.Text.RegularExpressions.RegexOptions.IgnoreCase; System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(pattern, opts); //フォルダ内にあるファイルを取得 System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(dirPath); System.IO.FileInfo[] files = dir.GetFiles(fileWildcards); foreach (System.IO.FileInfo f in files) { //一つずつファイルを調べる if (ContainTextInFile(f.FullName, reg)) fileCol.Add(f.FullName); } return (string[])fileCol.ToArray(typeof(string)); } //ファイルの内容がpatternに一致するか調べる private static bool ContainTextInFile( string filePath, System.Text.RegularExpressions.Regex reg) { //ファイルを読み込む System.IO.StreamReader strm = null; string txt = ""; try { strm = new System.IO.StreamReader( filePath, System.Text.Encoding.Default, true); txt = strm.ReadToEnd(); } finally { strm.Close(); } return reg.IsMatch(txt); }