首页 > 解决方案 > VB.net 文件处理进展缓慢

问题描述

嗨,我有一个应用程序,它获取文件列表并在每个文件中搜索每个文件中引用的所有图像。列表完成后,我对列表中的重复项进行排序并删除,然后将每个项目/图像复制到一个新文件夹中。它有效,但几乎没有。我需要几个小时才能在少至 500 个文件上进行复制。如果速度更快,则在 Windows 资源管理器中进行复制,这违背了应用程序的目的。我不知道如何更好地简化它。您的意见将不胜感激。

    'Remove Dupes takes the list of images found in each file and removes any duplicates

Private Sub RemoveDupes(ByRef Items As List(Of String), Optional ByVal NeedSorting As Boolean = False)

    statusText = "Removing duplicates from list."
    Dim Temp As New List(Of String)
    Items.Sort()

    'Remove Duplicates
        For Each Item As String In Items
        'Check if item is in Temp
        If Not Temp.Contains(Item) Then
            'Add item to list.
            Temp.Add(Item)
            File.AppendAllText(ListofGraphics, Item & vbNewLine)
        End If
    Next Item

    'Send back new list.
    Items = Temp
End Sub

'GetImages does the actual copying of files from the list RemoveDup creates

Public Sub GetImages()
    Dim imgLocation = txtSearchICN.Text
    ' Get the list of file
    Dim fileNames As String() = System.IO.Directory.GetFiles(imgLocation)
    Dim i As Integer
    statusText = "Copying image files."
    i = 0
    For Each name As String In GraphicList
        i = i + 1
        ' See whether name appears in fileNames.
        Dim found As Boolean = False
        ' Search name in fileNames.
        For Each fileName As String In fileNames
            ' GraphicList consists of filename without extension, so we compare name
            ' with the filename without its extension.
            If Path.GetFileNameWithoutExtension(fileName) = name Then
                Dim FileNameOnly = Path.GetFileName(fileName)
                ' Debug.Print("FileNameOnly: " & FileNameOnly)
                Dim copyTo As String
                copyTo = createImgFldr & "\" & FileNameOnly
                System.IO.File.Copy(fileName, copyTo)
                File.AppendAllText(ListofFiles, name & vbNewLine)
                'items to write to rich text box in BackgroundWorker1_ProgressChanged
                imgFilename = (name) + vbCrLf
                ImageCount1 = i
                ' Set found to True so we do not process name as missing, and exit For. \
                found = True
                Exit For
            Else
                File.AppendAllText(MissingFiles, name & vbNewLine)
            End If
        Next
        status = "Copying Graphic Files"
        BackgroundWorker1.ReportProgress(100 * i / GraphicList.Count())
    Next
End Sub
'BackgroundWorker1_ProgressChanged. gets file counts and writes to labels and rich text box

Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    '' This event is fired when you call the ReportProgress method from inside your DoWork.
    '' Any visual indicators about the progress should go here.

    ProgressBar1.Value = e.ProgressPercentage
    lblStatus.Text = CType(e.UserState, String)
    lblStatus.Text = status & " " & e.ProgressPercentage.ToString & " % Complete "
    RichTextBox1.Text &= (fileFilename)
    RichTextBox1.Text &= (imgFilename)
    txtImgCount.Text = ImageCount1
    Label8.Text = statusText
    fileCount.Text = fCount

End Sub

标签: vb.net

解决方案


我会更改您的代码中的某些内容,以避免在每个循环中不断写入文件以及嵌套两个循环的必要性。

这是您的 GetFiles 的精简版本,旨在突出我的观点:

Public Sub GetImages()

    ' Two list to collect missing and found files
    Dim foundFiles As List(Of String) = New List(Of String)()
    Dim notfoundFiles As List(Of String) = New List(Of String)()

    Dim fileNames As String() = System.IO.Directory.GetFiles(imgLocation)

    ' Loop over the filenames retrieved
    For Each fileName As String In fileNames

        ' Check if the files is contained or not in the request list
        If GraphicList.Contains(Path.GetFileNameWithoutExtension(fileName)) Then

            Dim FileNameOnly = Path.GetFileName(fileName)
            Dim copyTo As String
            copyTo = createImgFldr & "\" & FileNameOnly
            System.IO.File.Copy(fileName, copyTo)

            ' Do not write to file inside the loop, just add the fact to the list
            foundFiles.Add(FileNameOnly)
        Else
            notfoundFiles.Add(FileNameOnly)
        End If
    Next

    ' Write everything outside the loop
    File.WriteAllLines(listofFiles, foundFiles)
    File.WriteAllLines(MissingFiles, notfoundFiles)

End Sub

推荐阅读