Click here to Skip to main content
15,887,440 members
Articles / Programming Languages / C#
Tip/Trick

IO.Stream Read/Write Native Types

Rate me:
Please Sign up or sign in to vote.
3.00/5 (2 votes)
18 Dec 2015CPOL 8.2K   3  
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...

C++
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;
        }
    }

}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --