65.9K
CodeProject 正在变化。 阅读更多。
Home

IO.Stream 原生类型读/写

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (2投票s)

2015年12月19日

CPOL
viewsIcon

8667

使用扩展方法、Encoding 和 BitConverter 在 IO.Stream 对象上读写原生类型

引言

这是一个简单的 static 类,用于为 IO.Stream 类添加一些功能。它避免了使用 BinaryReaderBinaryWriter 的需要,同时添加了功能以简化写入 BinaryReaderBinaryWriter 未直接支持的类型,例如 DecimalDateTimeGuid。它还添加了一个用于读取和写入用户类的接口: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;
        }
    }

}
© . All rights reserved.