我需要合并这些文件夹,这些文件夹在每个目录中都有一吨文件。我会用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.Combine
和Path.GetFileName
的数量。我调用了没有目录...File
和完整路径...Path
的文件名。
我用StringComparer.OrdinalIgnoreCase
初始化了HashSet
,使其忽略文件名的字符大小写,因为Windows文件系统也忽略大小写。