IO.Stream Read/Write Native Types





3.00/5 (2 votes)
Use extension methods, Encoding, and BitConverter to read and write native types on an IO.Stream object
Introduction
This is a simple static
class to add some functionality to the IO.Stream
class. It avoids the need for BinaryReader
and BinaryWriter
, while adding functionality to simplify writing types not directly supported by BinaryReader
and BinaryWriter
, such as Decimal
, DateTime
, and Guid
. It also adds an interface for reading and writing user classes: the IBinaryIO
interface.
Using the code
The class is mostly comprised of extension methods for the Stream class which allow direct reading and writing of native types...
var mmsTmp = new MemoryStream();
mmsTmp.Write(DateTime.Now);
mmsTmp.Write(Guid.NewGuid());
mmsTmp.Write(decimal.MaxValue);
mmsTmp.Write((int)ushort.MaxValue);
The IBinaryIO interface allows for direct reading and writing of user classes...
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>()); } } } }
Then you can read and write the entire list with a Stream object...
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>(); }
Finally, here is the StreamExtensions class in all it's whatever-ness...
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; } } }