需要合并两个文件夹,每个文件夹中有数十万个文件.VB.net



我需要合并这些文件夹,这些文件夹在每个目录中都有一吨文件。我会用folder.copy,但那需要很长时间。

我大部分时间都在使用xcopy过程来处理这一问题,但我一直从xcopy中得到错误,说在没有副本的情况下有副本。因此,我正在努力寻找一种与xcopy一样快甚至更快的可靠方法。

我以前尝试过的是:

Private Sub MergeF(ByVal TargetFolder As String, ByVal MergeeFolder As String)
For Each F As String In IO.Directory.GetFiles(MergeeFolder)
If IO.File.Exists(IO.Path.Combine(TargetFolder, IO.Path.GetFileName(F))) Then
Dim FileA As New IO.FileInfo(IO.Path.Combine(
MergeeFolder, IO.Path.GetFileName(F)))
Dim FileB As New IO.FileInfo(IO.Path.Combine(
TargetFolder, IO.Path.GetFileName(F)))
If FileA.Length <> FileB.Length Then
Dim index As Integer = 1
Do
Dim NewFileName = IO.Path.Combine(TargetFolder,
IO.Path.GetFileName(F.Insert(F.Length - 4, CStr(index))))
If IO.File.Exists(NewFileName) Then
index += 1
Else
IO.File.Copy(F, NewFileName)
IO.File.Delete(F)
Exit Do
End If
Loop
End If
Else
IO.File.Move(IO.Path.Combine(MergeeFolder, IO.Path.GetFileName(F)),
IO.Path.Combine(TargetFolder, IO.Path.GetFileName(F)))
End If
Next
End Sub

https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories

async也应该加快速度;

https://learn.microsoft.com/en-us/dotnet/standard/io/asynchronous-file-i-o

如果这还不够快,那么我认为你的下一个选择是尝试直接的win32api

将代码转换为您可以使用的vb;

https://codeconverter.icsharpcode.net/或https://converter.telerik.com/

  • 祝你好运

实现的问题是在循环内部调用File.Exists。这会一次又一次地扫描目标目录中的文件,速度会变慢。更好的方法是将目标目录中文件的文件名加载到HashSet(of T(中。此集合中的查找速度非常快,比File.Exists快得多。

Private Sub MergeF(ByVal TargetFolder As String, ByVal MergeeFolder As String)
Dim targetFiles = New HashSet(Of String)(
IO.Directory.GetFiles(TargetFolder) _
.Select(Function(f) IO.Path.GetFileName(f)),
StringComparer.OrdinalIgnoreCase)
For Each sourcePath As String In IO.Directory.GetFiles(MergeeFolder)
Dim file As String = IO.Path.GetFileName(sourcePath)
Dim targetPath As String = IO.Path.Combine(TargetFolder, file)
If targetFiles.Contains(file) Then
Dim sourceInfo As New IO.FileInfo(sourcePath)
Dim targetInfo As New IO.FileInfo(targetPath)
If sourceInfo.Length <> targetInfo.Length Then
Dim index As Integer = 1
Do
Dim fileWithoutExt =
Path.GetFileNameWithoutExtension(file)
Dim extension = Path.GetExtension(file)
file = fileWithoutExt & index & extension
If targetFiles.Contains(file) Then
index += 1
Else
targetPath = IO.Path.Combine(TargetFolder, file)
targetFiles.Add(file) 'Upate the HashSet
IO.File.Move(sourcePath, targetPath)
Exit Do
End If
Loop
End If
Else
targetFiles.Add(file) 'Upate the HashSet
IO.File.Move(sourcePath, targetPath)
End If
Next
End Sub

注意,我还通过使用适当的变量减少了Path.CombinePath.GetFileName的数量。我调用了没有目录...File和完整路径...Path的文件名。

我用StringComparer.OrdinalIgnoreCase初始化了HashSet,使其忽略文件名的字符大小写,因为Windows文件系统也忽略大小写。

最新更新