【问题标题】:How can I display the progress of an action from another library on a file?如何在文件上显示来自另一个库的操作的进度?
【发布时间】:2012-08-04 01:06:19
【问题描述】:

我正在使用System.Security.Cryptography.SHA512Cng.ComputeHash 计算一个非常大的文件的 SHA-512 哈希值,我想为其显示一个进度条。如何在不重新实现算法的情况下检查方法的完成情况?

【问题讨论】:

    标签: .net vb.net stream hash


    【解决方案1】:

    你可以继承Stream!这是一个从文件中读取的ProgressStream

    Public Class ProgressStream
        Inherits FileStream
    
        Public Event ProgressChanged(sender As ProgressStream, progress As Integer)
    
        Public Sub New(fileName As String)
            MyBase.New(fileName, FileMode.Open, FileAccess.Read)
        End Sub
    
        Public ReadOnly Property Progress() As Integer
            Get
                Return CInt(Me.Position / Me.Length * 100)
            End Get
        End Property
    
        Public Overrides Function Read(array() As Byte, offset As Integer, count As Integer) As Integer
            Read = MyBase.Read(array, offset, count)
            RaiseEvent ProgressChanged(Me, Me.Progress)
        End Function
    End Class
    

    只需处理ProgressChanged 事件。

    同样的方法适用于所有其他类型的流,您也可以将它用于某些其他长时间运行的任务,这些任务根据需要而不是一次性读取文件。

    【讨论】:

      【解决方案2】:

      一种常见的方法是使用TransformBlockTransformFinalBlock 并以块的形式计算哈希。这使您不必关心您正在使用的流的类型,或者您可能想要散列多个流(例如目录中的所有文件)。

      这是一个小例子:

      Using stream As New FileStream("C:\somefile.dat", FileMode.Open),
            hash As New SHA512Cng()
          Const BUFFER_SIZE As Integer = 2048
          Dim buffer(BufferSize - 1) As Byte
          Dim bytesRead As Integer
      
          Do
              bytesRead = stream.Read(buffer, 0, BUFFER_SIZE)
              hash.TransformBlock(buffer, 0, bytesRead, buffer, 0)
      
              Dim percentComplete = stream.Position / stream.Length * 100
              'Handle percentComplete here somehow, perhaps with an event
          Loop While stream.Length - stream.Position > BUFFER_SIZE
      
          bytesRead = stream.Read(buffer, 0, BUFFER_SIZE) ' read the final block
          hash.TransformFinalBlock(buffer, 0, bytesRead)
      
          'We're now 100% complete, raise an event with 100% completion
          Dim theHash = hash.Hash 'The final hash values
      End Using
      

      缓冲区大小越小,结果越细粒度,但可能会以性能为代价。

      【讨论】:

      • 糟糕,我想我错过了。谢谢!
      猜你喜欢
      • 2020-10-14
      • 2021-12-03
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      相关资源
      最近更新 更多