C#整合两个Stream,大文件+盐Salt|C#整合两个Stream,大文件+盐Salt MD5方案

今天想使用C#,对一个文件Stream进行MD5,同时加入盐值(Salt)。
MD5函数的使用,要传入一个文件流Stream。
如果要在,对一个文件+Salt值进行MD5,就要要把整个文件加载到MemoryStream里,在和Salt合并。
如果文件太大,如果使用一个MemoryStream把FileStream拷贝进来,显然占用太大量的内存了。
这时候,我们需要把MemoryStream和FileStream合并成一个Stream。
逛StackOverflow找到一个MergedStream的方案,整合两个Stream:
http://stackoverflow.com/questions/878837/salting-a-c-sharp-md5-computehash-on-a-stream
【C#整合两个Stream,大文件+盐Salt|C#整合两个Stream,大文件+盐Salt MD5方案】整理一下以后,就可以使用既对大文件友好又带盐值的MD5函数了。

#region https://github.com/mr-kelly// KKUpdater - Robust Resources Package Downloader // // A private module of KSFramework // // Author: chenpeilin / mr-kelly // Email: 23110388@qq.com // Website: https://github.com/mr-kelly#endregionusing System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace KKUpdater { /// ///merge two stream ///http://stackoverflow.com/questions/878837/salting-a-c-sharp-md5-computehash-on-a-stream /// public class MergedStream : Stream, IDisposable { private Stream s1; private Stream s2; public MergedStream(Stream first, Stream second) { s1 = first; s2 = second; }public override int Read(byte[] buffer, int offset, int count) { int s1count = (int) Math.Min((long) count, s1.Length - s1.Position); int bytesRead = 0; if (s1count > 0) { bytesRead += s1.Read(buffer, offset, s1count); }if (s1count < count) { bytesRead += s2.Read(buffer, offset + s1count, count - s1count); }return bytesRead; }public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException("Merged stream not support write!"); }public override bool CanRead { get { return s1.CanRead && s2.CanRead; } }public override bool CanSeek { get { return s1.CanSeek && s2.CanSeek; } }public override bool CanWrite { get { return s1.CanWrite && s2.CanWrite; } }public override void Flush() { s1.Flush(); s2.Flush(); }public override long Length { get { return s1.Length + s2.Length; } }public override long Position { get { return s1.Position + s2.Position; } set { throw new NotImplementedException(); } }public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); }public override void SetLength(long value) { throw new NotImplementedException(); }void IDisposable.Dispose() { s1.Dispose(); s2.Dispose(); } } }

    推荐阅读