The example below first creates an AsyncStream with a 100KB buffer to wrap a FileStream, uses it to compute an SHA512 hash, and finally uses AlternateStreams to write the hash to an alternate data stream named "sha512" for future reference (of course, a more sophisticated implementation would also save the file's current "last modified" time to detect when the file changes and the hash must be recomputed).
Using an FileStream wrapped by an AsyncStream instead of a FileStream alone significantly improves performance because the AsyncStream can asynchronously read from the underlying FileStream while the hash is being computed, whereas reading from an "unwrapped" FileStream requires blocking, during which time hashing cannot be performed.
The following performance of SHA512Managed.ComputeHash(Stream) was observed for a 4GB file [testing methodology]:

With a 100KB buffer, a stream other than AsyncStream required approximately 50% more time on the test machine. To try the below code with an "unrwapped" FileStream, simply comment out the "AsyncStream stream =..." line and uncomment the "FileStream stream =..." line. You can also run the SHA512 test on your own machine using the test package.
using System; using System.IO; using System.Security.Cryptography; using BetterStreams; namespace BetterStreamsExamples { static class HashTagger { public static void SHA512Tag(string filename) { //Create an AsyncStream with a 100KB buffer AsyncStream stream = new AsyncStream(File.OpenRead(filename), AsyncStreamMode.Reading, 102400); //Using an unwrapped FileStream yields significantly worse performance: //FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 102400); //Compute the SHA512 hash SHA512Managed sha512 = new SHA512Managed(); byte[] hash = sha512.ComputeHash(stream); stream.Close(); FileStream alternateStream = AlternateStreams.OpenStream(filename, "sha512", FileMode.Create); alternateStream.Write(hash, 0, 64); //write the 512-bit (64 byte) hash alternateStream.Close(); } } } |