私はVB.NETでこれを書いていましたが、私はC#でも快適です。私は、Windowsファイルシステム上で見つけたいファイルのリストを持っています。ファイル名に基づいて、別のディレクトリを調べる必要があります。私が持っているファイルのリストは、(動作する)プログラムの先頭にコンパイルし、ソートされていないDataTableに格納されているリストです。ここに私のアプローチがあります。ファイル番号の数を減らすことはできますか?
ファイルのDataTableの一覧ファイル名に基づいに見て
- a_111.txt
- a_222.txt
- b_333.txt
- a_444.txt
- c_555.txt
- b_666.txt
ディレクトリ(これは1,000s +で時々、日々異なります)
C:\a\ -- for files begin with a (variable name is A_folder)
C:\b\ -- for files begin with b (variable name is B_folder)
C:\c\ -- for files begin with c (variable name is C_folder)
コード:
If DataTableofFiles IsNot Nothing AndAlso DataTableofFiles.Rows.Count > 0 Then
For Each row as DataRow In DataTableofFiles.Rows
If row("FILENAME").ToString.StartsWith("a") Then
Dim a_WriteResultstoA as String = "a.csv"
functionfindfiles(A_folder, row("FILENAME").ToString, a_WriteResultstoA)
ElseIf row("FILENAME").ToString.StartsWith("b") Then
Dim b_WriteResultstoB as String = "b.csv"
functionfindfiles(B_folder, row("FILENAME").ToString, b_WriteResultstoB)
ElseIf row("FILENAME").ToString.StartsWith("C") Then
Dim c_WriteResultstoC as String = "c.csv"
functionfindfiles(C_folder, row("FILENAME").ToString, c_WriteResultstoC)
End If
Next
End If
Private Sub functionfindfiles(sourcefolder As String, filename as String, writetofile As String)
Try
For Each f As String In Directory.EnumerateFiles(sourcefolder, "*.*", SearchOption.AllDirectories) '<-- file enumeration
If Path.GetFileName(f).Equals(filename, StringComparison.OrdinalIgnoreCase) Then
Using fs As New FileStream(writetofile, FileMode.Append, FileAccess.Write, FileShare.Write)
Using sw As StreamWriter = New StreamWriter(fs)
If Not New FileInfo(writetofile).Length > 0 Then
For i As Integer = 0 To DataTableofFiles.Columns.Count - 1 Step 1
sw.Write(DataTableofFiles.Columns(i).ToString)
If i < DataTableofFiles.Columns.Count - 1 Then
sw.Write(",")
End If
Next
sw.WriteLine()
End If
For Each row As DataRow In DataTableofFiles.Rows
If row("FILENAME").ToString = filename Then
For i As Integer = 0 To DataTableofFiles.Columns.Count - 1 Step 1
If Not Convert.IsDBNull(row(i)) Then
sw.Write(row(i).ToString.Replace(vbLf, "").Replace(",", ";"))
End If
If i < DataTableofFiles.Columns.Count - 1 Then
sw.Write(",")
End If
Next
sw.WriteLine()
End If
Next
End Using
End Using
Else
'write results that are not found here to a file
End If
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
この場合、ファイルシステムの列挙は6回発生します。ディレクトリにたくさんのファイルがあると、実行に本当に時間がかかることがあります。ファイル列挙の量を減らす良い方法がありますか?または、コード内の他の領域を改善して、必要以上に実行される追加の操作を減らすことができますか?アドバイスをいただければ幸いです。ありがとう!
あなたのforeach'sを逆転させます。 {foreach(file in EnumerateFiles){}} 'を実行しますが、foreach(enumerateFiles内のファイル){foreach(リスト内のファイル名){}}'にそれらを逆順にすることができます。あなたのメソッドが何をするのか、どのように呼び出すのかのアーキテクチャを変更する必要がありますが、論理的には二重foreachがすべてです。コードがすべてインライン展開されている場合は、foreachの順序を自明に逆転できます1回だけ。 – Quantic
返事をありがとう。注文を元に戻すと、ForEachが検索するためにどのような「フォルダパス」が渡されるのか分かりません。 – Jayarikahs