I'm computing the SHA-512 hash of a very large file using System.Security.Cryptography.SHA512Cng.ComputeHash, and I'd like to show a progress bar for it. How can I check the completion of the method without reimplementing the algorithm?
You can subclass Stream! Here's a ProgressStream that reads from a file:
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
Just handle the ProgressChanged event.
The same method applies to all other types of streams, and you can also use it for certain other long-running tasks that read a file as required instead of all at once.
A common approach is to use the TransformBlock and TransformFinalBlock and compute the hash in chunks. This allows you to not care about the type of stream you are working with, or maybe you want to hash more than one stream (say all the files in a directory).
Here's a little example:
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
The smaller the buffer size, the more fine-grained the result, but possibly at the cost of performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With