自己在项目中总结了一些数据格式转换的方法,贴在这里备用,后续如果有其他的格式转换要求或方法,也贴在这里:
1 /// <summary> 2 /// 字节数组转换类,主要实现的均是代码中可能要用到的,未用到的暂时不提供。此类涉及电脑大小端的判断。 3 /// </summary> 4 public static class BitConvertHelper 5 { 6 public static string ConvertEndpointToIpStr(EndPoint endPoint) 7 { 8 var remote = endPoint as IPEndPoint; 9 if (remote != null) 10 { 11 return remote.Address.ToString(); 12 } 13 return null; 14 } 15 16 public static byte[] UInt16ToNetworkBytes(ushort data) 17 { 18 return BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data)); 19 } 20 21 /// <summary> 22 /// 将当前的制板时间转换为字节数组,配置模式中有用 23 /// </summary> 24 /// <returns></returns> 25 public static byte[] ConvertDataTimeToBytes(DateTime? dataTime) 26 { 27 if (dataTime == null) 28 throw new ArgumentNullException("dataTime"); 29 30 int year = dataTime.Value.Year - 2000; 31 32 if (year < 0 || year > 125) 33 { 34 return new byte[3]; 35 } 36 37 return new byte[3] { (byte)year, (byte)dataTime.Value.Month, (byte)dataTime.Value.Day }; 38 } 39 40 public static DateTime ConvertBytesToDateTime(byte[] bytes, int start) 41 { 42 int year = bytes[start] + 2000; 43 int month = bytes[start + 1]; 44 int day = bytes[start + 2]; 45 return new DateTime(year, month, day); 46 } 47 /// <summary> 48 /// 将字符串形式的地址转成字节数组 49 /// </summary> 50 /// <param name="addr"></param> 51 /// <param name="seperator"></param> 52 /// <returns></returns> 53 public static byte[] ConvertAddrStrToBytes(string addr, char seperator) 54 { 55 if (addr == null) 56 throw new ArgumentNullException("addr"); 57 var items = addr.Split(seperator); 58 return items.Select(item => Convert.ToByte(item)).ToArray(); 59 } 60 61 /// <summary> 62 /// 63 /// </summary> 64 /// <param name="addr"></param> 65 /// <param name="seperator"></param> 66 /// <returns></returns> 67 public static string ConvertToString(IEnumerable<byte> addr, char seperator) 68 { 69 var sb = new StringBuilder(); 70 foreach (var a in addr) 71 { 72 sb.Append(a.ToString("X2")).Append(seperator); 73 } 74 var str = sb.ToString(); 75 return str.TrimEnd(seperator); 76 } 77 78 public static string ConvertBytesToStr(byte[] scr, int start, int end, char seperator) 79 { 80 var sb = new StringBuilder(); 81 for (int i = start; i < end; i++) 82 { 83 sb.Append(scr[i].ToString("X2")).Append(seperator); 84 } 85 var str = sb.ToString(); 86 return str.TrimEnd(seperator); 87 } 88 89 /// <summary> 90 /// Converts a hex string to a byte array. 91 /// </summary> 92 /// <param name="hex">The hex string</param> 93 /// <returns>Array of bytes</returns> 94 public static byte[] HexToBytes(string hex) 95 { 96 if (hex == null) 97 throw new ArgumentNullException("hex"); 98 99 if (hex.Length % 2 != 0) 100 throw new FormatException("Hex character count is not even!"); 101 102 var bytes = new byte[hex.Length / 2]; 103 104 for (int i = 0; i < bytes.Length; i++) 105 bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); 106 107 return bytes; 108 } 109 110 public static byte GetByte(byte[] dataBytes,int offset) 111 { 112 return dataBytes[offset]; 113 } 114 115 public static byte[] GetBytes(byte[] dataBytes, int offset, int length) 116 { 117 var data = new byte[length]; 118 Buffer.BlockCopy(dataBytes, offset, data, 0, length); 119 return data; 120 121 //return dataBytes.Slice(offset, length); //此方案效率较低 122 } 123 124 //public static ushort ConvertToUshort(byte[] dataBytes, int offset) 125 //{ 126 // var bytes = TryReverseBytes(GetBytes(dataBytes,offset,2)); 127 // return BitConverter.ToUInt16(bytes, 0); 128 //} 129 130 public static ushort ConvertToUshort(byte[] dataBytes, int startIndex) 131 { 132 return (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBytes, startIndex)); 133 } 134 135 public static uint ConvertToUint(byte[] dataBytes, int offset) 136 { 137 var bytes = TryReverseBytes(GetBytes(dataBytes, offset, 4)); 138 return BitConverter.ToUInt32(bytes, 0); 139 } 140 141 /// <summary> 142 /// 某些情况下有效位数可能不是4个字节,但需要转换为uint类型 143 /// </summary> 144 /// <param name="dataBytes"></param> 145 /// <param name="offset"></param> 146 /// <param name="length">要转换为uint的字节个数</param> 147 /// <returns></returns> 148 public static uint ConvertToUint(byte[] dataBytes, int offset, int length) 149 { 150 if (length > 4 || length <= 0) 151 { 152 throw new ArgumentOutOfRangeException("length"); 153 } 154 var bytes = new byte[4]; 155 var bytesUsage = GetBytes(dataBytes, offset, length); 156 Buffer.BlockCopy(bytesUsage, 0, bytes, 4 - length, length); 157 bytes = TryReverseBytes(bytes); 158 return BitConverter.ToUInt32(bytes, 0); 159 } 160 161 public static uint[] NetworkBytesToHostUint32(byte[] networkBytes) 162 { 163 if (networkBytes == null) 164 throw new ArgumentNullException("networkBytes"); 165 166 if (networkBytes.Length%2 != 0) 167 throw new FormatException("NetworkBytesNotEven"); 168 169 uint[] result = new uint[networkBytes.Length >> 2]; 170 171 for (int i = 0; i < result.Length; i++) 172 result[i] = (uint) IPAddress.NetworkToHostOrder(BitConverter.ToInt32(networkBytes, i*4)); 173 174 return result; 175 } 176 177 /// <summary> 178 /// 将数组中byte数据转换为uint.自己注意start和end的范围, 179 /// </summary> 180 /// <param name="networkBytes"></param> 181 /// <param name="start">包含start,0开始</param> 182 /// <param name="end">不包含end</param> 183 /// <returns></returns> 184 public static uint[] NetworkBytesToHostUint32(byte[] networkBytes, int start, int end) 185 { 186 if (networkBytes == null) 187 throw new ArgumentNullException("networkBytes"); 188 189 var length = end - start; 190 191 if (length % 2 != 0) 192 throw new FormatException("NetworkBytesNotEven"); 193 194 var result = new uint[length >> 2]; 195 196 for (int i = 0; i < result.Length; i++) 197 result[i] = (uint) IPAddress.NetworkToHostOrder(BitConverter.ToInt32(networkBytes, start + i << 2)); 198 199 return result; 200 } 201 202 /// <summary> 203 /// 直接将数据写入传入的数组,不再重新申请空间,todo:此函数不是通用函数,是为了数据采集部分方便而编写 204 /// </summary> 205 /// <param name="srcNetworkBytes"></param> 206 /// <param name="srcStart"></param> 207 /// <param name="srcEnd"></param> 208 /// <param name="dstUints"></param> 209 /// <param name="dstStarti"></param> 210 /// <param name="dstStartj"></param> 211 public static void NetworkBytesToUint32Array(byte[] srcNetworkBytes, int srcStart, int srcEnd, uint[,] dstUints, 212 int dstStarti,int dstStartj) 213 { 214 if (srcNetworkBytes == null) 215 throw new ArgumentNullException("srcNetworkBytes"); 216 if (dstUints == null) 217 throw new ArgumentNullException("dstUints"); 218 219 var length = srcEnd - srcStart; 220 221 if (length % 2 != 0) 222 throw new FormatException("NetworkBytesNotEven"); 223 224 for (int i = 0; i < length >> 2; i++) 225 dstUints[dstStarti,dstStartj + i] = 226 (uint) IPAddress.NetworkToHostOrder(BitConverter.ToInt32(srcNetworkBytes, srcStart + (i << 2))); 227 } 228 229 230 public static int ConvertToInt(byte[] dataBytes, int offset) 231 { 232 var bytes = TryReverseBytes(GetBytes(dataBytes, offset, 4)); 233 return BitConverter.ToInt32(bytes, 0); 234 } 235 236 //public static int ConvertToInt(byte[] dataBytes, int offset, int length) 237 //{ 238 // if (length > 4 || length <= 0) 239 // { 240 // throw new ArgumentOutOfRangeException("length"); 241 // } 242 // var bytes = new byte[4]; 243 // var bytesUsage = GetBytes(dataBytes, offset, length); 244 // Buffer.BlockCopy(bytesUsage, 0, bytes, 4 - length, length); 245 // bytes = TryReverseBytes(bytes); 246 // return BitConverter.ToInt32(bytes, 0); 247 //} 248 249 public static int ConvertToInt(byte[] dataBytes, int startIndex, int length) 250 { 251 if (length > 4 || length <= 0) 252 { 253 throw new ArgumentOutOfRangeException("length"); 254 } 255 var bytes = new byte[4]; 256 Buffer.BlockCopy(GetBytes(dataBytes, startIndex, length), 0, bytes, 4 - length, length); 257 return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bytes, 0)); 258 } 259 260 public static void BigEndianBlockCopy(uint[,] src, int srcOffset, byte[] dst, int dstOffset, int byteCounts) 261 { 262 //获取要拷贝的uint的个数 263 int uintCount = byteCounts/sizeof (uint); 264 int uintSrcOffset = srcOffset/sizeof (uint); 265 int endSrcOffset = uintCount + uintSrcOffset; 266 var uintBytes = new byte[sizeof(uint)]; 267 int uintIndex = 0; 268 int byteIndex = 0; 269 270 foreach (var u in src) 271 { 272 if (uintIndex >= uintSrcOffset) 273 { 274 CopyBytes(u, 4, uintBytes, 0); 275 Buffer.BlockCopy(uintBytes, 0, dst, dstOffset + byteIndex, 4); 276 byteIndex += 4; 277 } 278 uintIndex++; 279 if (uintIndex >= endSrcOffset) 280 { 281 break; 282 } 283 } 284 } 285 286 public static void CopyBytes(uint value, int bytes, byte[] buffer, int index) 287 { 288 int endOffset = index + bytes - 1; 289 for (int i = 0; i < bytes; i++) 290 { 291 buffer[endOffset - i] = unchecked((byte) (value & 0xff)); 292 value = value >> 8; 293 } 294 } 295 296 297 public static bool IsLittleEndian() 298 { 299 return BitConverter.IsLittleEndian; 300 } 301 302 /// <summary> 303 /// Attention:将自己翻转 304 /// </summary> 305 /// <param name="bytes"></param> 306 /// <returns></returns> 307 private static byte[] TryReverseBytes(byte[] bytes) 308 { 309 if (IsLittleEndian()) 310 { 311 bytes = ReverseBytes(bytes); 312 } 313 return bytes; 314 } 315 316 /// <summary> 317 /// 翻转字节数组,数据以大端形式传输,不同的电脑直接顺序不同,可能是小端,因此需要翻转字节数组 318 /// </summary> 319 /// <param name="inArray"></param> 320 /// <returns></returns> 321 public static byte[] ReverseBytes(byte[] inArray) 322 { 323 byte temp; 324 int highCtr = inArray.Length - 1; 325 326 for (int ctr = 0; ctr < inArray.Length/2; ctr++) 327 { 328 temp = inArray[ctr]; 329 inArray[ctr] = inArray[highCtr]; 330 inArray[highCtr] = temp; 331 highCtr -= 1; 332 } 333 return inArray; 334 } 335 336 public static IEnumerable<T> Slice<T>(this IEnumerable<T> source, int startIndex, int size) 337 { 338 if (source == null) 339 throw new ArgumentNullException("source"); 340 var enumerable = source as T[] ?? source.ToArray(); 341 int num = enumerable.Count(); 342 if (startIndex < 0 || num < startIndex) 343 throw new ArgumentOutOfRangeException("startIndex"); 344 if (size < 0 || startIndex + size > num) 345 throw new ArgumentOutOfRangeException("size"); 346 347 return enumerable.Skip(startIndex).Take(size); 348 } 349 350 public static T[] Slice<T>(this T[] source, int startIndex, int size) 351 { 352 if (source == null) 353 throw new ArgumentNullException("source"); 354 int num = source.Count(); 355 if (startIndex < 0 || num < startIndex) 356 throw new ArgumentOutOfRangeException("startIndex"); 357 if (size < 0 || startIndex + size > num) 358 throw new ArgumentOutOfRangeException("size"); 359 360 return source.Skip(startIndex).Take(size).ToArray(); 361 } 362 }