IO.Stream 原生类型读/写





3.00/5 (2投票s)
使用扩展方法、Encoding 和 BitConverter 在 IO.Stream 对象上读写原生类型
引言
这是一个简单的 static
类,用于为 IO.Stream
类添加一些功能。它避免了使用 BinaryReader
和 BinaryWriter
的需要,同时添加了功能以简化写入 BinaryReader
和 BinaryWriter
未直接支持的类型,例如 Decimal
、DateTime
和 Guid
。它还添加了一个用于读取和写入用户类的接口:IBinaryIO
接口。
使用代码
该类主要由 Stream 类的扩展方法组成,允许直接读取和写入原生类型...
var mmsTmp = new MemoryStream();
mmsTmp.Write(DateTime.Now);
mmsTmp.Write(Guid.NewGuid());
mmsTmp.Write(decimal.MaxValue);
mmsTmp.Write((int)ushort.MaxValue);
IBinaryIO 接口允许直接读取和写入用户类...
class ValueData :StreamExtensions.IBinaryIO { public Guid ID = new Guid() ; // 16 bytes public DateTime DateCreated = DateTime.Now; // 8 bytes (1 long) public Decimal CurrentValue = Decimal.Zero; // 16 bytes (4 ints) public void WriteTo(Stream stream) { stream.Write(ID ); stream.Write(DateCreated ); stream.Write(CurrentValue); } public void ReadFrom(Stream stream) { ID = stream.ReadGuid() ; DateCreated = stream.ReadDateTime(); CurrentValue = stream.ReadDecimal() ; } public class Collection :StreamExtions.IBinaryIO { private List<ValueData> _lstData = new List<ValueData>(); public void Populate(int entries) { for(int i = 0; i < entries; i++) { _lstData.Add(new ValueData()); } } public void WriteTo(Stream stream) { stream.Write(_lstData.Count); foreach(ValueData vld in _lstData) { stream.Write(vld); } } public void ReadFrom(Stream stream) { int iCount = stream.ReadInt32(); for(int i = 0; i < iCount; i++) { _lstData.Add(stream.Read<ValueData>()); } } } }
然后可以使用 Stream 对象读取和写入整个列表...
using(var mmsTmp = new MemoryStream()) { // write... var lstTmp = new ValueData.Collection(); lstTmp.Populate(100); mmsTmp.Write(lstTmp); // read... mmsTmp.Position = 0; var lstVerify = stream.Read<ValueData.List>(); }
最后,这是 StreamExtensions 类,其所有内容如下...
using System; using System.IO; using System.Text; namespace NativeExtensions { public static class StreamExtensions { public interface IBinaryIO { void WriteTo(Stream stream); void ReadFrom(Stream stream); } public static void Write(this Stream stream, bool value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, byte value) { var abTmp = new byte[] { value }; stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, sbyte value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, short value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, ushort value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, int value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, uint value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, long value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, ulong value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, float value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, double value) { var abTmp = BitConverter.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, decimal value) { var aiTmp = decimal.GetBits(value); foreach(var i in aiTmp) { var abTmp_i = BitConverter.GetBytes(i); stream.Write(abTmp_i, 0, abTmp_i.Length); } } public static void Write(this Stream stream, DateTime value) { var abTmp = BitConverter.GetBytes(value.Ticks); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, TimeSpan value) { var abTmp = BitConverter.GetBytes(value.Ticks); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, char[] value) { var abTmp = Encoding.ASCII.GetBytes(value); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, string value) { stream.Write(value.Length); stream.Write(value.ToCharArray()); } public static void Write(this Stream stream, byte[] value) { stream.Write(value, 0, value.Length); } public static void Write(this Stream stream, Guid value) { var abTmp = value.ToByteArray(); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, Stream source, int count) { var abTmp = new byte[count]; source.Read(abTmp, 0, abTmp.Length); stream.Write(abTmp, 0, abTmp.Length); } public static void Write(this Stream stream, IBinaryIO value) { value.WriteTo(stream); } public static bool ReadBool(this Stream stream) { var abTmp = new byte[sizeof(bool)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToBoolean(abTmp, 0); } public static sbyte ReadSByte(this Stream stream) { return Convert.ToSByte(stream.ReadByte()); } public static short ReadInt16(this Stream stream) { var abTmp = new byte[sizeof(short)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToInt16(abTmp, 0); } public static ushort ReadUInt16(this Stream stream) { var abTmp = new byte[sizeof(ushort)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToUInt16(abTmp, 0); } public static int ReadInt32(this Stream stream) { var abTmp = new byte[sizeof(int)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToInt32(abTmp, 0); } public static uint ReadUInt32(this Stream stream) { var abTmp = new byte[sizeof(uint)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToUInt32(abTmp, 0); } public static long ReadInt64(this Stream stream) { var abTmp = new byte[sizeof(long)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToInt64(abTmp, 0); } public static ulong ReadUInt64(this Stream stream) { var abTmp = new byte[sizeof(ulong)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToUInt64(abTmp, 0); } public static float ReadSingle(this Stream stream) { var abTmp = new byte[sizeof(float)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToSingle(abTmp, 0); } public static double ReadDouble(this Stream stream) { var abTmp = new byte[sizeof(double)]; stream.Read(abTmp, 0, abTmp.Length); return BitConverter.ToDouble(abTmp, 0); } public static decimal ReadDecimal(this Stream stream) { var aiTmp = new int[4]; for(int i = 0; i < 4; i++) { var abTmp_i = new byte[sizeof(int)]; stream.Read(abTmp_i, 0, abTmp_i.Length); aiTmp[i] = BitConverter.ToInt32(abTmp_i, 0); } return new decimal(aiTmp); } public static DateTime ReadDateTime(this Stream stream) { var abTmp = new byte[sizeof(long)]; stream.Read(abTmp, 0, abTmp.Length); return new DateTime(BitConverter.ToInt64(abTmp, 0)); } public static TimeSpan ReadTimeSpan(this Stream stream) { var abTmp = new byte[sizeof(long)]; stream.Read(abTmp, 0, abTmp.Length); return new TimeSpan(BitConverter.ToInt64(abTmp, 0)); } public static char[] ReadChars(this Stream stream, int count) { var abTmp = new byte[sizeof(char) * count]; stream.Read(abTmp, 0, abTmp.Length); return Encoding.ASCII.GetChars(abTmp); } public static string ReadString(this Stream stream) { return new string(stream.ReadChars(stream.ReadInt32())); } public static byte[] ReadBytes(this Stream stream, int count) { var ret = new byte[count]; stream.Read(ret, 0, ret.Length); return ret; } public static Guid ReadGuid(this Stream stream) { var abTmp = Guid.Empty.ToByteArray(); stream.Read(abTmp, 0, abTmp.Length); return new Guid(abTmp); } public static T Read<T>(this Stream stream) where T : IBinaryIO { var ret = default(T); ret.ReadFrom(stream); return ret; } } }