【问题标题】:Need to merge 2 folders that have hundreds of thousands of files in each. VB.net需要合并 2 个文件夹,每个文件夹都有数十万个文件。 VB.net
【发布时间】:2021-06-14 13:17:05
【问题描述】:

我需要合并这些在每个目录中都有大量文件的文件夹。我会使用 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

【问题讨论】:

  • XCopy 按名称确定重复项,而不是按内容或文件日期。

标签: vb.net file merge copy xcopy


【解决方案1】:

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

异步也应该加快速度;

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

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

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

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

  • 祝你好运!

【讨论】:

  • 今天早上我又看到了这个,这一次有几十万注册,我会推荐一个如下奥利弗所说的某种索引!
【解决方案2】:

你的实现的问题是你在循环内调用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文件系统也会忽略大小写。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-08
    • 2020-09-05
    • 2021-05-27
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多