0

感谢阅读 - 我正在使用下面的类来计算指定文件的 CRC32 校验和。

我的问题是如何将文件完成的进度(以 % 为单位)报告到不同表单上的进度条。我已经在 New() 子下尝试了 (i / count) * 100 但我没有任何运气,或者为此设置进度条。任何人都可以帮忙吗?

提前致谢

史蒂夫

Public Class CRC32

Private crc32Table() As Integer
Private Const BUFFER_SIZE As Integer = 1024

Public Function GetCrc32(ByRef stream As System.IO.Stream) As Integer

    Dim crc32Result As Integer
    crc32Result = &HFFFFFFFF

    Dim buffer(BUFFER_SIZE) As Byte
    Dim readSize As Integer = BUFFER_SIZE

    Dim count As Integer = stream.Read(buffer, 0, readSize)
    Dim i As Integer
    Dim iLookup As Integer

    Do While (count > 0)
        For i = 0 To count - 1

            iLookup = (crc32Result And &HFF) Xor buffer(i)
            crc32Result = ((crc32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
            crc32Result = crc32Result Xor crc32Table(iLookup)
        Next i


        count = stream.Read(buffer, 0, readSize)
    Loop

    GetCrc32 = Not (crc32Result)

End Function

Public Sub New()


    Dim dwPolynomial As Integer = &HEDB88320
    Dim i As Integer, j As Integer

    ReDim crc32Table(256)
    Dim dwCrc As Integer

    For i = 0 To 255
    Form1.CRCWorker.ReportProgress((i / 255) * 100)  'Report Progress
        dwCrc = i
        For j = 8 To 1 Step -1
            If (dwCrc And 1) Then
                dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                dwCrc = dwCrc Xor dwPolynomial
            Else
                dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
            End If
        Next j

        crc32Table(i) = dwCrc
    Next i

    'file complete
End Sub

End Class
  '------------- END CRC32 CLASS--------------
   '-------------- START FORM1 --------------------------
Private Sub CRCWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles CRCWorker.DoWork

 For i = CurrentInt To dgv.Rows.Count - 1
              CRCWorker.ReportProgress(0, i & "/" & Total_Files)
              Current_File_Num = (i + 1)
              SetControlText(lblCurrentFile, Str(Current_File_Num) & "/" & Total_Files)
              result = CheckFile(SFV_Parent_Directory & "\" & dgv.Rows(i).Cells(0).Value, dgv.Rows(i).Cells(1).Value)
           Select Case result
               Case 0 ' missing file
                   UpdateRow(i, 2, "MISSING")
                   'dgv.Rows(i).Cells(2).Value = "MISSING"
                    Missing_Files = Missing_Files + 1
                    SetControlText(lblMissingFiles, Str(Missing_Files))
               Case 1 ' crc match
                    UpdateRow(i, 2, "OK")
                  ' dgv.Rows(i).Cells(2).Value = "OK"
                    Good_Files = Good_Files + 1
                    SetControlText(lblGoodFiles, Str(Good_Files))
              Case 2 'crc bad
                    UpdateRow(i, 2, "BAD")
                    ' dgv.Rows(i).Cells(2).Value = "BAD"
                    Bad_Files = Bad_Files + 1
                    SetControlText(lblBadFiles, Str(Bad_Files))
            End Select
            If CRCWorker.CancellationPending = True Then
                e.Cancel = True
                Exit Sub
            End If


      Next
       End Sub
    Private Sub CRCWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles CRCWorker.ProgressChanged

    Dim val As Integer = e.ProgressPercentage
    ProgressBar2.Maximum = 100
    ProgressBar2.Value = e.ProgressPercentage
    Debug.Print(val)

    End Sub

     Function CheckFile(ByVal tocheck_filepath As String, ByVal expected_crc As String) As Integer 'returns result of a file check 0 = missing 1 = good 2 = bad

    If File.Exists(tocheck_filepath) = False Then
        Return 0 'return file missing
    End If
    Dim f As FileStream = New FileStream(tocheck_filepath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
    Dim c As New CRC32()

    crc = c.GetCrc32(f)
    Dim crcResult As String = "00000000"
    crcResult = String.Format("{0:X8}", crc) 
    f.Close()

End Function
4

2 回答 2

2

您的 .ReportProgress() 调用似乎在 New() 子例程中,这是为 CRC 计算制作查找表的部分。New() 子例程在主 CRC 例程之前调用一次。主要的CRC例程是占用所有时间并且需要进度条的例程。

进度条更新不应该在 GetCrc32() 函数中吗?像这样的东西:

    Public Function GetCrc32(ByRef stream As System.IO.Stream, _
                             Optional prbr As ProgressBar = Nothing) As UInteger
    Dim crc As UInteger = Not CUInt(0)
    Dim buffer(BUFFER_SIZE) As Byte
    Dim readSize As Integer = BUFFER_SIZE
    Dim left As Long = stream.Length
    If Not (prbr Is Nothing) Then ' ProgressBar setup for counting down amount left.
        prbr.Maximum = 100 
        prbr.Minimum = 0 
        prbr.Value = 100
    End If
    Dim count As Integer : Do
        count = stream.Read(buffer, 0, readSize)
        For i As Integer = 0 To count - 1
            crc = (crc >> 8) Xor tbl((crc And 255) Xor buffer(i))
        Next
        If Not (prbr Is Nothing) Then ' ProgressBar updated here
            left -= count 
            prbr.Value = CInt(left * 100 \ stream.Length)
            prbr.Refresh()
        End If
    Loop While count > 0
    Return Not crc
End Function
于 2012-10-07T06:30:47.630 回答
1

在 Windows 窗体中, BackgroundWorker 类通常用于在另一个线程中运行密集型任务并在不阻塞界面的情况下更新进度条。 在 VB.Net 中使用 BackgroundWorker 的示例

问题是当您在代码中使用表单而不实例化它Form1.CRCWorker.ReportProgress((i / 255) * 100)时,会发生一种隐藏的“自动实例化Form1”,并且每次都会创建新的实例。

于 2012-08-22T22:30:33.473 回答