// 2016.01.08 サブフォルダの検索指定ができるよう機能追加。 // ファイルを開くときにIOExceptionが発生した場合、 // 処理を続行するよう修正。 // 出力結果の表示をListBoxからListViewへ変更。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace MyFindAndGrep { public partial class Form1 : Form { public Form1() { InitializeComponent(); // ListViewを詳細表示に設定 listView_Result.View = View.Details; // ListViewにタイトル行を追加 listView_Result.Columns.Add( "ファイル名" ); listView_Result.Columns.Add( "行の内容" ); } private void button1_Click( object sender, EventArgs e ) { int ret = 0; if ( ( textBox_Folder.Text.Count() <= 0 ) || ( textBox_Letter.Text.Count() <= 0 ) ) { MessageBox.Show( "対象フォルダと検索文字列を" + "入力してください。" , "Question" , MessageBoxButtons.OK , MessageBoxIcon.Question ); return; } // リストボックスの消去 listView_Result.Items.Clear(); // find+grepの実行 ret = DoFindAndGrep( textBox_Folder.Text , textBox_Letter.Text , checkBox_SubFolder.Checked , listView_Result ); // 結果表示 MessageBox.Show( "検索が終わりました。\n" + "終了コード:" + ret , "Information" , MessageBoxButtons.OK , MessageBoxIcon.Information ); } private int DoFindAndGrep( string folder , string letter , bool subfolder , ListView listView_Result ) { int ret = 0; // サブフォルダーの検索指示があるか if ( subfolder ) { // 指定されたディレクトリ配下の // ディレクトリを取得 string[] dirs = Directory.GetDirectories( folder ); foreach ( string s in dirs ) { // 再帰呼び出し ret = DoFindAndGrep( s , letter , subfolder , listView_Result ); } } // 指定されたディレクトリ配下のファイルを取得 string[] files = Directory.GetFiles( folder ); foreach( string file_path in files ) { try { ret = DoFileRead( file_path , letter , listView_Result ); if (ret != 0) { break; } } catch ( IOException ioe ) { // ファイルが別のプロセスで使用中だと // IOExceptionが発生する。 string[] row = { file_path , ioe.Message }; listView_Result .Items.Add( new ListViewItem( row ) ); } } return ret; } private int DoFileRead( string file_path , string letter , ListView listView_Result ) { int ret = 0; // ファイルを開く StreamReader sr = new StreamReader( file_path , Encoding.GetEncoding( "Shift_JIS" ) ); // ファイルを1行ずつ読み込む string line = ""; for ( int i = 0; ; i++ ) { line = sr.ReadLine(); if ( line == null ) { break; } ret = DoGrep( line, letter ); if ( ret == 0 ) { // 取得結果をListViewへ設定 string[] row = { file_path , line }; listView_Result .Items.Add( new ListViewItem( row ) ); } } // ファイルを閉じる sr.Close(); return 0; } private int DoGrep( string line , string letter ) { // lineにletterが含まれるか調べる int idx = line.IndexOf( letter ); if ( idx >= 0 ) { // 含まれる return 0; } // 含まれない return -1; } // 検索フォルダを選択するボタンの処理 private void button2_Click( object sender, EventArgs e ) { FolderBrowserDialog fbd = new FolderBrowserDialog(); // 説明テキスト fbd.Description = "フォルダを指定してください"; // デフォルトフォルダー fbd.RootFolder = Environment.SpecialFolder.Desktop; // ダイアログを表示 DialogResult rslt = fbd.ShowDialog( this ); if ( rslt == DialogResult.OK ) { textBox_Folder.Text = fbd.SelectedPath; textBox_Letter.Focus(); } } // 出力結果(リストの内容)をファイルに書き出す // ボタンの処理 private void button3_Click( object sender, EventArgs e ) { // 出力リストの件数を確認 if ( listView_Result.Items.Count <= 0 ) { // 結果表示 MessageBox.Show( "出力する内容がありません。" , "Information" , MessageBoxButtons.OK , MessageBoxIcon.Exclamation ); return; } SaveFileDialog sfd = new SaveFileDialog(); // 説明テキスト sfd.Title = "保存先のファイルを指定してください"; // 保存するファイルの名前 sfd.FileName = textBox_Letter.Text + ".txt"; // ダイアログを表示 DialogResult rslt = sfd.ShowDialog( this ); if ( rslt != DialogResult.OK ) { return; } // ファイルを開く StreamWriter sw = new StreamWriter( sfd.FileName , true , Encoding.GetEncoding( "Shift_JIS" ) ); // 取得した出力リストの内容を1行ずつファイルに // 書き込む for ( int i = 0; i < listView_Result.Items.Count; i++ ) { ListViewItem item = listView_Result.Items[i]; sw.WriteLine( item.SubItems[0].Text + "\t" + item.SubItems[1].Text ); } // ファイルを閉じる sw.Close(); // 結果表示 MessageBox.Show( "リストの内容をファイルに出力しました。\n" + "ファイル名:" + sfd.FileName , "Information" , MessageBoxButtons.OK , MessageBoxIcon.Information ); } } }