您的位置:首页 > 编程语言 > C#

C# 从字节数组读取基础数据

2016-08-16 15:44 232 查看
C#的byte[]和AS3中的ByteArray都是字节数组.但是明显的AS3的ByteArray更加好用一些.因为在ByteArray当中有一个position属性,可以读取相应的字节后,自动指向下一个没有读取的字节的index.这样你永远不用自己再建一个index来手动的处理这件事情了.当然,ByteArray还有其他的一些方法和属性,是byte[]没有的.我这里强调,并非贬低C#,只是在这一块,需要做一些多余的事情,显得相当的繁琐.为此我封装了一个类库,核心类 BytesDecode 如下:

//=====================================================================
//
//  All right reserved
//  filename : BytesDecode
//  description :
//
//  create by User at 2016/8/12 9:57:15
//=====================================================================
using System;
using System.Runtime.InteropServices;

namespace BytesLib.com
{
/// <summary>
/// 解析字节流
/// </summary>
internal sealed class BytesDecode
{
/// <summary>
/// 解析基础值类型
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="bytes">字节流数组</param>
/// <param name="index">开始Index</param>
/// <returns></returns>
public T getStructValue<T>(byte[] bytes, ref int index) where T : struct
{
return this.getValue<T>(bytes, ref index);
}
/// <summary>
/// 解析基础值类型数组
/// </summary>
/// <typeparam name="T">基础类型</typeparam>
/// <param name="bytes">字节流数组</param>
/// <param name="index">开始Index</param>
/// <param name="len">数组长度</param>
/// <returns></returns>
public T[] getStructValus<T>(byte[] bytes, ref int index, int len) where T : struct
{
return this.getValues<T>(bytes, ref index, len);
}
/// <summary>
/// 基础值类型2维数组解析
/// </summary>
/// <typeparam name="T">基础类型</typeparam>
/// <param name="bytes">字节流数组</param>
/// <param name="index">开始Index</param>
/// <param name="lenD1">一维Length</param>
/// <param name="lenD2">二维Length</param>
/// <returns></returns>
public T[,] getStructValus2D<T>(byte[] bytes, ref int index, int lenD1, int lenD2) where T : struct
{
return this.getValues2D<T>(bytes, ref index, lenD1, lenD2);
}
#region
/// <summary>
/// 基础值类型解析
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="bytes">字节流数组</param>
/// <param name="index">开始Index</param>
/// <returns></returns>
private T getValue<T>(byte[] bytes, ref int index) where T : struct
{
T bc = default(T);
switch (typeof(T).Name.ToLower())
{
case "uint16":
{
bc = (T)Convert.ChangeType( BitConverter.ToUInt16(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "int16":
{
bc = (T)Convert.ChangeType(BitConverter.ToInt16(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "bool":
case "boolean":
{
bc = (T)Convert.ChangeType(BitConverter.ToBoolean(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "int64":
{
bc = (T)Convert.ChangeType(BitConverter.ToInt64(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "uint64":
{
bc = (T)Convert.ChangeType(BitConverter.ToUInt64(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "byte":
{
bc = (T)Convert.ChangeType( bytes[index], typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "int32":
{
bc = (T)Convert.ChangeType(BitConverter.ToInt32(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
case "uint32":
{
bc = (T)Convert.ChangeType(BitConverter.ToUInt32(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
break;
}
return bc;
}
/// <summary>
/// 基础值类型数组解析
/// </summary>
/// <typeparam name="T">基础类型</typeparam>
/// <param name="bytes">字节流数组</param>
/// <param name="index">开始Index</param>
/// <param name="len">数组长度</param>
/// <returns></returns>
private T[] getValues<T>(byte[] bytes, ref int index, int len) where T : struct
{
T[] bc = new T[len];
int i = 0;
switch (typeof(T).Name.ToLower())
{
case "uint16":
{
while (i < len)
{
bc[i] = (T) Convert.ChangeType(BitConverter.ToUInt16(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "int16":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(BitConverter.ToInt16(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "bool":
case "boolean":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(BitConverter.ToBoolean(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "int64":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(BitConverter.ToInt64(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "uint64":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(BitConverter.ToUInt64(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "byte":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(bytes[index], typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "int32":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(BitConverter.ToInt32(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "uint32":
{
while (i < len)
{
bc[i] = (T)Convert.ChangeType(BitConverter.ToUInt32(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
i += 1;
}
}
break;
case "char":
{
Buffer.BlockCopy( bytes, index, bc, 0,len );
index += Marshal.SizeOf(bc);
}
break;
}
return bc;
}
/// <summary>
/// 基础值类型2维数组解析
/// </summary>
/// <typeparam name="T">基础类型</typeparam>
/// <param name="bytes">字节流数组</param>
/// <param name="index">开始Index</param>
/// <param name="lenD1">一维Length</param>
/// <param name="lenD2">二维Length</param>
/// <returns></returns>
private T[,] getValues2D<T>(byte[] bytes, ref int index, int lenD1, int lenD2) where T : struct
{
T[,] bc = new T[lenD1,lenD2];
int i = 0;
switch (typeof(T).Name.ToLower())
{
case "uint16":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j+=1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToUInt16(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "int16":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToInt16(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "bool":
case "boolean":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToBoolean(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "int64":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToInt64(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "uint64":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToUInt64(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "byte":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(bytes[index], typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "int32":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToInt32(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "uint32":
{
while (i < lenD1)
{
for (int j = 0; j < lenD2; j += 1)
{
bc[i, j] = (T)Convert.ChangeType(BitConverter.ToUInt32(bytes, index), typeof(T));
index += Marshal.SizeOf(typeof(T));
}
i += 1;
}
}
break;
case "char":
{
Buffer.BlockCopy(bytes, index, bc, 0, lenD1*lenD2);
index += Marshal.SizeOf(bc);
}
break;
}
return bc;
}
#endregion
}
}
本类可以解析: 基础数据 , 基础数据一维数组 , 基础数据二维数组

在此额外奉上 基础数组2byte[]
//将基元数据类型数组转换成字节数组
public static byte[] ToBytes<T>(T[] array) where T : struct
{
if (array == null)
{
throw new ArgumentNullException("array");
}
var bytes = new byte[Buffer.ByteLength(array)];
Buffer.BlockCopy(array, 0, bytes, 0, bytes.Length);
return bytes;
}
public static byte[] ToBytes<T>(T[,] array) where T : struct
{
if (array == null)
{
throw new ArgumentNullException("array");
}
var bytes = new byte[Buffer.ByteLength(array)];
Buffer.BlockCopy(array, 0, bytes, 0, bytes.Length);
return bytes;
}
补充说明:

这个包是为Unity开发的.当然要知道它支持FrameWork的版本号了. 在PlayerSettings当中.关于如何使用FrameWork2.0来编译类库,自己Google



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数组 字节 读取