掲示板お問い合わせランダムジャンプ



この広告は60日以上更新がないブログに表示されております。 新しい記事を書くことで広告を消すことができます。

Top Index

2005年11月20日
サブディレクトリを含めたファイル検索
ファイル数が多くなると、どうしても各所に散らばってしまい、
どこに保存したかを忘れてしまいます。

そんなときはファイル検索プログラムを書いてみましょう。
DirectoryクラスのGetFilesメソッドを使えば間単にファイル検索ができます。

しかし、GetFileメソッドは同一フォルダ内しか検索ができないため、
サブフォルダまでは検索してくれません。残念!

そこでサブフォルダまでを検索できるクラスを作ってみました。
(お暇な方がいましたら、ぜひご自分でも作ってみてください。
(再起呼び出しの勉強になりますので。

以下、ソース。
01Imports System.IO
02Imports System.Text.RegularExpressions
03
04Public Class IndexDirectory
05    Private _IndexFilePath As String
06
07    'インデックスファイル指定なし
08    Public Sub New()
09        Me.IndexFilePath = Path.Combine(Path.GetTempPath, Path.GetTempFileName)
10    End Sub
11
12    'インデックスファイル指定あり
13    Public Sub New(ByVal IndexFilePath As String)
14        Me.IndexFilePath = IndexFilePath
15    End Sub
16
17    'インデックスファイルパス
18    Public Property IndexFilePath() As String
19        Get
20            Return _IndexFilePath
21        End Get
22        Set(ByVal Value As String)
23            _IndexFilePath = Value
24        End Set
25    End Property
26
27    'インデックスファイルの作成(複数ディレクトリ)
28    Public Sub CreateIndexFile(ByVal ParamArray Args() As Object)
29        'ファイルを作り直す
30        Try
31            If File.Exists(Me.IndexFilePath) Then File.Delete(Me.IndexFilePath)
32            File.CreateText(Me.IndexFilePath).Close()
33        Catch ex As Exception
34            Throw New Exception("インデックスファイルの作成に失敗しました。", ex)
35        End Try
36
37        Dim em As IEnumerator = Args.GetEnumerator
38        While em.MoveNext
39            Dim D As String = DirectCast(em.Current, String)
40            If Not Directory.Exists(D) Then D = Path.GetDirectoryName(D)
41
42            CreateIndexFile(D)
43        End While
44    End Sub
45
46    'インデックスファイルの作成(単一ディレクトリ)
47    Private Sub CreateIndexFile(ByVal DirectoryName As String)
48        Try
49            Dim em As IEnumerator = Directory.GetDirectories(DirectoryName).GetEnumerator
50            While em.MoveNext
51                Dim D As String = DirectCast(em.Current, String)
52                Me.CreateIndexFile(D)
53
54                Dim Files As String() = Directory.GetFiles(D)
55                Me.WriteIndexFile(Files)
56            End While
57        Catch ex As Exception
58            'フォルダへのアクセス権がない場合、ここでCatchだけしておく。
59        End Try
60    End Sub
61
62    'インデックスファイルへの書き込み
63    Private Sub WriteIndexFile(ByVal Files As String())
64        Dim sw As IO.StreamWriter
65        Dim em As IEnumerator = Files.GetEnumerator
66
67        Try
68            sw = New IO.StreamWriter(Me.IndexFilePath, True)
69            While em.MoveNext
70                sw.WriteLine(DirectCast(em.Current, String))
71            End While
72        Catch ex As Exception
73            Throw New Exception("インデックスファイルの書き込みに失敗しました。", ex)
74        Finally
75            sw.Close()
76        End Try
77    End Sub
78
79    'インデックスファイルから、正規表現を用いてファイル名を探す
80    Public Function GetFiles(ByVal pattern As StringAs ArrayList
81        Dim sr As IO.StreamReader
82        Dim Files As ArrayList = New ArrayList
83
84        Try
85            sr = New IO.StreamReader(Me.IndexFilePath)
86            Dim s As String = sr.ReadLine
87            Do Until (s = Nothing)
88                If Regex.IsMatch(Path.GetFileName(s), pattern) Then Files.Add(s)
89                s = sr.ReadLine
90            Loop
91        Catch ex As Exception
92            Throw New Exception("インデックスファイルの読込に失敗しました。", ex)
93        Finally
94            sr.Close()
95        End Try
96
97        Return Files
98    End Function
99End Class
 powered by vb2html ver2.1b


ぱっと見で気づくかもしれませんが、
これはクラスなので、ちょっとわかりにくいと思います。

このクラスを使った実際の検索メインルーチンのページで補足したいと思います。


[ 投稿者:mk3008 at 20:27 | VB.NETコーディングTips | コメント(4) | トラックバック(1) ]

この記事へのコメント
インデックスファイルの作成が中断されます。
「お」と申します。

57 Catch ex As Exception
58 'フォルダへのアクセス権がない場合、ここでCatchだけしておく。

とすると、アクセス権のないフォルダが現れた時点で、インデックスファイルの作成が中断されます。
その次のフォルダに処理を移さなければならないということはわかりましたが、具体的にどうコーディングすればいいかわかりません。

mk3008さん、お教えください。
投稿者: at 2007-09-21 13:25:58
try~catchの使い方をマスターしましょう
「お」さん、こんにちは。お返事遅れて失礼しました。

質問に対して、簡潔に返答するならば
「catchだけすればいいです」
というコメント文と同じ返答になってしまいますので・・・^^;

以下のことがわかれば、謎は簡単に解決できます。
 1.try~catch構文の動作
 2.ネストしたtry~catch構文の動作

「1」についてはさすがにコメントでは説明しきれないので省略しますが、
「2」についてはサンプルコードを書くことで簡単に検証できます。

たとえば・・
  Private Sub Button1_Click(...略...) Handles Button1.Click
    Try
      Try
        Throw New ApplicationException("意図的にエラーを発生させます")
      Catch ex As Exception
        MessageBox.Show("エラーをキャッチ1")
      End Try
    Catch ex As Exception
      MessageBox.Show("エラーをキャッチ2")
    End Try
  End Sub
と書くと、
 ・エラーメッセージは何が表示されますか?
 ・エラーメッセージは何個表示されますか?
予想をしたうえでテスト実行してみてください。

検証した上で、以下のようにしてみてください。
  Private Sub Button1_Click(...略...) Handles Button1.Click
    Try
      Try
        Throw New ApplicationException("意図的にエラーを発生させます")
      Catch ex As Exception
        'なにも書かない
      End Try
    Catch ex As Exception
      MessageBox.Show("エラーをキャッチ2")
    End Try
  End Sub
ご理解いただけましたでしょうか?

try~catchはエラー処理の上でとても重要な構文ですので、理解しておいて損はないですので、
MSDNをみたり、本を読んでみたり、小さな実証コードを書いてみるといいかと思います。
( 特に、構文に関することは、実用書(「x日でデキル」とか)ではなく、
( 構文解説書を購入されることをお勧めします。


・余談
以下のように書くとどうなるかもぜひ知っておいてください。
  Private Sub Button1_Click(...略...) Handles Button1.Click
    Try
      Try
        Throw New ApplicationException("意図的にエラーを発生させます")
      Catch ex As Exception
        Throw ex
      End Try
    Catch ex As Exception
      MessageBox.Show("エラーをキャッチ2")
    End Try
  End Sub
投稿者: mk3008 at 2007-09-26 14:12:10
ネストしたtry~catch構文を用いるとは気付きませんでした
「お」です。

ネストしたtry~catch構文を用いるとは気付きませんでした。

コーディングもうまくいきました。(と思います。)

どうもありがとうございました。

プログラムソースを投稿したいのですが、うまくいきません。
何か制限をかけておられるのですか?
投稿者: at 2007-09-27 21:40:34
お役に立てて幸いです。
コメントに特別な制限はしていませんが、
1コメントのデータ量が多いと
ブログがエラーを返すかも知れませんね。
投稿者: mk3008 at 2007-09-28 09:39:03

この記事へのトラックバック
サブディレクトリを含めたファイル検索 サンプル
こちらに掲載してあるクラスの呼び出し例です。http://shinshu...
投稿者: VB.NETで作る! at 2005-11-20 20:54:33

この記事へのトラックバックURL
http://shinshu.fm/MHz/88.44/a03195/0000090296.trackback

この記事の固定URL
http://shinshu.fm/MHz/88.44/archives/0000090296.html

記事へのコメント
 
認証コード:
画像に表示されるコードを半角英数字で入力して下さい。画像が読み難い場合はこちら
簡単演算認証: 6 x 4 =
計算の答えを半角英数字で入力して下さい。
名前: [必須]
URL/Email:
タイトル:
コメント:
※記事・コメントなどの削除要請はこちら