ThreadSafeStream 类(NetworkComms 2.3.1源码了解和学习)
networkComms.net2.3.1开源版本,基于gpl V3协议。因为不能公开3.x版本的源码,所以基于此版本进行学习。3.X版本进行了诸多改进和Bug修复,使用方法上两者相差不大。 /*请注意使用以下代码,需遵循GplV3协议*/ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Security.Cryptography; namespace DPSBase { /// <summary> /// 线程安全的数据流 数据流的包装器确保以线程安全的方式访问数据流 /// </summary> public class ThreadSafeStream : IDisposable { private Stream stream; private object streamLocker = new object(); /// <summary> /// ///如果设定为True 内部的数据流在数据写入到网络后将会释放 /// </summary> public bool CloseStreamAfterSend { get; private set; } /// <summary> /// 创建一个线程安全的数据流 /// </summary> /// <param name="stream">The stream to make thread safe</param> public ThreadSafeStream(Stream stream) { this.CloseStreamAfterSend = false; this.stream = stream; } /// <summary> /// 创建一个线程安全的数据流 /// </summary> /// <param name="stream">The stream to make thread safe</param> public ThreadSafeStream(Stream stream, bool closeStreamAfterSend) { this.CloseStreamAfterSend = closeStreamAfterSend; this.stream = stream; } /// <summary> /// 内部数据流的总长度 /// </summary> public long Length { get { lock (streamLocker) return stream.Length; } } /// <summary> /// 内部数据流 位置 /// </summary> public long Position { get { lock (streamLocker) return stream.Position; } } /// <summary> /// 从数据流种返回数据 /// </summary> /// <param name="numberZeroBytesPrefex"> </param> /// <returns></returns> public byte[] ToArray(int numberZeroBytesPrefex = 0) { lock (streamLocker) { stream.Seek(0, SeekOrigin.Begin); byte[] returnData = new byte[stream.Length + numberZeroBytesPrefex]; //把数据读取到数组的指定位置 stream.Read(returnData, numberZeroBytesPrefex, returnData.Length - numberZeroBytesPrefex); return returnData; } } /// <summary> /// 从数据流的制定位置返回数据 /// </summary> public byte[] ToArray(long start, long length, int numberZeroBytesPrefex = 0) { if (length>int.MaxValue) throw new ArgumentOutOfRangeException( "length", "Unable to return array whose size is larger than int.MaxValue. Consider requesting multiple smaller arrays."); lock (streamLocker) { if (start + length > stream.Length) throw new ArgumentOutOfRangeException("length", "Provided start and length parameters reference past the end of the available stream."); //定位到指定位置 stream.Seek(start, SeekOrigin.Begin); byte[] returnData = new byte[length + numberZeroBytesPrefex]; //从指定位置读取指定长度的数据 到字节数组的指定位置 stream.Read(returnData, numberZeroBytesPrefex, returnData.Length - numberZeroBytesPrefex); return returnData; } } /// <summary> /// 返回MD5的值 /// </summary> /// <returns></returns> public string MD5CheckSum() { lock (streamLocker) { return MD5Stream(stream); } } public string MD5CheckSum(long start, int length) { using (MemoryStream partialStream = new MemoryStream(length)) { lock (streamLocker) { //从存储数据流的指定开始位置读取指定长度的数据到目标数据流中,并返回其MD5值 StreamWriteWithTimeout.Write(stream, start, length, partialStream, 8000, 1000, 500); return MD5Stream(partialStream); } } } /// <summary> /// 计算md5的值 /// </summary> /// <param name="streamToMD5">The stream to calcualte Md5 for</param> /// <returns></returns> private static string MD5Stream(Stream streamToMD5) { streamToMD5.Seek(0, SeekOrigin.Begin); #if WINDOWS_PHONE using(var md5 = new DPSBase.MD5Managed()) { #else using (var md5 = System.Security.Cryptography.MD5.Create()) { #endif return BitConverter.ToString(md5.ComputeHash(streamToMD5)).Replace("-", ""); } } /// <summary> /// 把数据拷贝到数据流的指定位置 /// </summary> /// <param name="data"></param> /// <param name="startPosition"></param> public void Write(byte[] data, long startPosition) { if (data == null) throw new ArgumentNullException("data"); lock (streamLocker) { //定位到数据流的指定位置 stream.Seek(startPosition, SeekOrigin.Begin); //把缓冲数据拷贝的数据流中 stream.Write(data, 0, data.Length); stream.Flush(); } }
//在英文网站上购买 九折折扣代码: NCDN_PRCLW
//淘宝正版销售 http://shop115882994.taobao.com/ 推广期间 八折优惠
/// <summary> /// 把当前类数据流中指定开始位置指定长度的数据拷贝到目标数据流中 /// </summary> public double CopyTo(Stream destinationStream, long startPosition, long length, int writeBufferSize, double timeoutMSPerKBWrite = 1000, int minTimeoutMS = 500) { lock (streamLocker) return StreamWriteWithTimeout.Write(stream, startPosition, length, destinationStream, writeBufferSize, timeoutMSPerKBWrite, minTimeoutMS); } /// <summary> /// Call Dispose on the internal stream /// 释放当前数据流 /// </summary> public void Dispose() { lock (streamLocker) stream.Dispose(); } /// <summary> /// Call Close on the internal stream /// </summary> public void Close() { lock (streamLocker) stream.Close(); } } } http://www.cnblogs.com/networkcomms http://www.networkcoms.cn 编辑
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。