让操作更方便:从传输报文的位操作到byte扩展

  由于项目的需要,我们经常需要对报文的某个字段设置位。但是传输报文是以byte[]存储的,为了解析报文,可能不得不进行转换,如果要设置位,也不得不进行转换。这样来回频繁的转换严重降低了程序的性能。那么能不能不转换,而直接对其操作呢?我想你也希望这样,不过遗憾的是微软提供的byte不具有直接操作。那么我们就来扩展一下,也让它支持这个操作。

 一、byte扩展——位操作方法

  1.获取指定的索引位。

 1             /// <summary>
 2             /// 获取取byte第index位(扩展方法)
 3             /// </summary>
 4             /// <param name="b">当前byte</param>
 5             /// <param name="index">byte第index位 
 6             /// <para>    index从0开始  </para></param>
 7             /// <returns></returns>
 8             public static int GetBit(this byte b, int index)
 9             {
10                 return ((b & (1 << index)) > 0)?1:0;
11             }

  2.设置指定索引位

 1             /// <summary>
 2             /// 设置byte第index位(扩展方法)
 3             /// </summary>
 4             /// <param name="b">当前byte</param>
 5             /// <param name="index">byte第index位
 6             /// <para>    index从0开始  </para></param>
 7             /// <returns></returns>
 8             public static byte SetBit(this byte b, int index)
 9             {
10                 return (byte)(b | (1 << index));
11             }

  3.清零指定的索引位

            /// <summary>
            /// 清零byte第index位(扩展方法)
            /// </summary>
            /// <param name="b">当前byte</param>
            /// <param name="index">byte第index位
            /// <para>    index从0开始  </para></param>
            /// <returns></returns>
            public static byte ClearBit(this byte b, int index)
            {
                return (byte)(b & ~(1 << index));
            }

  4.取反指定的索引位

 1             /// <summary>
 2             /// 取反byte第index位(扩展方法)
 3             /// </summary>
 4             /// <param name="b">当前byte</param>
 5             /// <param name="index">byte第index位
 6             /// <para>    index从0开始  </para></param>
 7             /// <returns></returns>
 8             public static byte ReverseBit(this byte b, int index)
 9             {
10                 b ^= (byte)(1 << index);
11                 return b;
12             }

 二、byte扩展——进制的字符串方法

  报文中有时不仅设置位,有时还需要显示指定的byte。这样我们也需要作一些扩展方法。

View Code
 1             /// <summary>
 2             /// 转换为二进制字符串(扩展方法)
 3             /// </summary>
 4             /// <param name="b">当前byte</param>
 5             /// <returns></returns>       
 6             public static string ToBinaryString(this byte b)
 7             {
 8                 return Convert.ToString(b, 2).PadLeft(8, '0');
 9             }
10             /// <summary>
11             /// 转换为16进制字符串(扩展方法)
12             /// </summary>
13             /// <param name="b">当前byte</param>
14             /// <returns></returns>
15             public static string ToHexString(this byte b)
16             {
17                 return b.ToString("X2");
18             }
19             /// <summary>
20             /// 转换为16进制字符串(扩展方法)
21             /// </summary>
22             /// <param name="bytes">当前byte泛型枚举接口</param>
23             /// <returns></returns>
24             public static string ToHexString(this IEnumerable<byte> bytes)
25             {
26                 StringBuilder sb = new StringBuilder();
27                 foreach (byte b in bytes)
28                 {
29                     sb.Append(b.ToString("X2") + " ");
30                 }
31                 return sb.ToString().TrimEnd();
32             }
33             /// <summary>
34             /// Base64数字编码
35             /// </summary>
36             /// <param name="bytes">当前byte数组</param>
37             /// <returns></returns>
38             public static string ToBase64String(this byte[] bytes)
39             {
40                 return Convert.ToBase64String(bytes);
41             }
42             /// <summary>
43             /// 转换为Int16有符号的整形数
44             /// </summary>
45             /// <param name="b">当前byte</param>
46             /// <returns></returns>
47             public static int ToInt16(this byte b)
48             {
49                 return Convert.ToInt16(b);
50             }
51             /// <summary>
52             /// 转换为指定编码的字符串 
53             /// </summary>
54             /// <param name="data">当前byt数据数组</param>
55             /// <param name="encoding">Encoding</param>
56             /// <returns></returns>
57             public static string Decode(this byte[] data, Encoding encoding)
58             {
59                 return encoding.GetString(data);
60             }

 

三、byte扩展——IO方法

  有时还需要对byte[] 进行一些IO操作,以存储或者转换为内存流。

View Code
 1             /// <summary>
 2             /// 保存为文件
 3             /// </summary>
 4             /// <param name="data">当前data数据</param>
 5             /// <param name="path">文件名(含路径的文件名)</param>
 6             public static void Save(this byte[] data, string path)
 7             {
 8                 System.IO.File.WriteAllBytes(path, data);
 9             }
10             /// <summary>
11             /// 转换为内存流 
12             /// </summary>
13             /// <param name="data">当前data数据</param>
14             /// <returns></returns>
15             public static System.IO.MemoryStream ToMemoryStream(this byte[] data)
16             {
17                 return new System.IO.MemoryStream(data);
18             }

 

以上扩展虽是一个简单的方法,确给我们操作带来极大的方便,扩展可以让我们对byte操作变得更加容易。下面是使用

 1             byte a = 0x78;//01111000
 2             Console.WriteLine(a.ToBinaryString());
 3             byte bb=a.SetBit(1);//把第一位设置为1,索引从右边开始,从0开始
 4             Console.WriteLine(bb.ToBinaryString());
 5             Console.WriteLine(bb.ToHexString());
 6             bb = a.ClearBit(1);//清除索引第1位
 7             Console.WriteLine(bb.ToBinaryString());
 8             Console.WriteLine(bb.ToHexString());
 9             bb = a.ReverseBit(1);//取反索引第1位
10             Console.WriteLine(bb.ToBinaryString());
11             Console.WriteLine(bb.ToHexString());

 

 

 

 

 

posted @ 2013-01-24 15:54  thickThinker  阅读(338)  评论(0编辑  收藏  举报