I wrote this in VB.NET, but I am comfortable with C# as well. I have a list of files that I want to find on a Windows file system. Based on the file name, I will need to look in a different directory. The list of files that I have is a list that I compiled at the beginning of the program (which works) and it is stored in a DataTable that is not sorted. Here is my approach.
DataTable List of Files (this can vary from day to day, sometimes in the 1,000s+)
- a_111.txt
- a_222.txt
- b_333.txt
- a_444.txt
- c_555.txt
- b_666.txt
Directories to look into based on file name
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)
Code:
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
In this case, the Enumeration on the file system will occur 6 times. The execution can take a really long time if I have a lot of files in the directories. Is there a better approach that will reduce the amount of file enumerations? Or other areas in the code that can be improved to reduce additional operations being performed more than needed? Any advice is greatly appreciated. Thanks!