J'ai écrit ceci dans VB.NET, mais je suis aussi à l'aise avec C#. J'ai une liste de fichiers que je veux trouver sur un système de fichiers Windows. Basé sur le nom de fichier, je devrai regarder dans un répertoire différent. La liste des fichiers que j'ai est une liste que j'ai compilée au début du programme (qui fonctionne) et elle est stockée dans un DataTable qui n'est pas trié. Voici mon approche.Est-il possible de réduire le nombre de numéros de fichiers?
DataTable Liste des fichiers (cela peut varier de jour en jour, parfois dans les 1,000s +)
- a_111.txt
- a_222.txt
- b_333.txt
- a_444.txt
- c_555.txt
- b_666.txt
répertoires à regarder en fonction du nom de fichier
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
Dans ce cas, l'énumération sur le système de fichiers aura lieu 6 fois. L'exécution peut prendre beaucoup de temps si j'ai beaucoup de fichiers dans les répertoires. Y a-t-il une meilleure approche qui réduira le nombre d'énumérations de fichiers? Ou d'autres zones du code qui peuvent être améliorées pour réduire les opérations supplémentaires effectuées plus que nécessaire? Tout conseil est grandement appréciée. Merci!
Inversez votre foreach. En ce moment vous faites 'foreach (nomFichier dans la liste) {foreach (fichier dans EnumerateFiles) {}}', mais vous pouvez simplement les retourner à 'foreach (fichier dans EnumerateFiles) {foreach (nomFichier dans la liste) {}}'. Vous devrez changer l'architecture de ce que font vos méthodes et comment vous les appelez, mais logiquement le double foreach est tout ce que vous faites et si le code était tout en ligne, vous pourriez inverser trivialement l'ordre des 'foreach' à énumérer juste une fois. – Quantic
Merci pour la réponse. Si j'ai inversé la commande, je ne saurai pas quel "chemin de dossier" passer pour le ForEach à rechercher. – Jayarikahs