让操作更方便:从传输报文的位操作到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());
作者:ThickThinker
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


浙公网安备 33010602011771号