我正在使用 计算一个非常大的文件的 SHA-512 哈希System.Security.Cryptography.SHA512Cng.ComputeHash
,我想为其显示一个进度条。如何在不重新实现算法的情况下检查方法的完成情况?
问问题
233 次
2 回答
2
你可以子类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
事件。
相同的方法适用于所有其他类型的流,您还可以将它用于某些其他长时间运行的任务,这些任务根据需要而不是一次性读取文件。
于 2012-08-04T01:06:19.107 回答
2
一种常见的方法是使用TransformBlock
andTransformFinalBlock
并以块的形式计算散列。这使您不必关心正在使用的流的类型,或者您可能想要散列多个流(例如目录中的所有文件)。
这是一个小例子:
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
缓冲区大小越小,结果越细粒度,但可能会以性能为代价。
于 2012-08-04T02:04:54.680 回答