dotnet C# 將 Byte 二進位制陣列使用不安全程式碼快速轉換為 int 或結構體陣列
阿新 • • 發佈:2021-01-30
技術標籤:# dotnetcorec#WPFC#dotnetWPF
我在寫一個有趣的 WPF 應用,我會不斷收到從硬體發過來的資料,這些資料被使用 Byte[] 陣列進行傳輸。我想要使用最快的方法轉換為我的 int 陣列或者轉換為結構體陣列,此時可以使用不安全程式碼的方式轉換
假定有一個二進位制陣列 Byte[] 是使用如下程式碼建立的
var memoryStream = new MemoryStream();
var binaryWriter = new BinaryWriter(memoryStream);
for (int i = 0; i < 100; i++)
{
binaryWriter.Write(i);
}
memoryStream.Position = 0;
var byteList = memoryStream.ToArray();
也就是說本質這是一個 int 陣列,在獲取到 byteList 時,可以如何快速轉換為 int 陣列使用?如果使用不安全程式碼,那麼轉換邏輯將會非常簡單
unsafe
{
var length = byteList.Length / sizeof(int);
fixed (byte* bytePointer = byteList)
{
int* intList = (int*) bytePointer;
// 這裡就獲取到了 int 陣列,雖然這是一個指標的陣列
for (int i = 0; i < length; i++)
{
int value = *intList;
Console.WriteLine(value);
intList++;
}
}
}
在使用不安全程式碼的時候,需要在專案屬性生成裡面勾選允許不安全程式碼,或者在csproj中新增下面程式碼
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
而如果此時的 byte 陣列的內容實際是某個結構體呢?例如我有一個結構體定義如下
[StructLayout(LayoutKind.Sequential)]
struct FooStruct
{
public int N1 { get; set; }
public int N2 { get; set; }
public int N3 { get; set; }
}
使用這個程式碼寫入到二進位制
for (int i = 0; i < 100; i++)
{
var fooStruct = new FooStruct()
{
N1 = i,
N2 = i,
N3 = i
};
binaryWriter.Write(fooStruct.N1);
binaryWriter.Write(fooStruct.N2);
binaryWriter.Write(fooStruct.N3);
}
memoryStream.Position = 0;
byteList = memoryStream.ToArray();
此時和上面程式碼差不多,只是使用對應的結構體強行轉換指標就可以
unsafe
{
var length = byteList.Length / sizeof(FooStruct);
fixed (byte* bytePointer = byteList)
{
var fooStructList = (FooStruct*) bytePointer;
for (int i = 0; i < length; i++)
{
var fooStruct = *fooStructList;
// 此時就獲取到了結構體陣列
}
}
}
通過這個方法,雖然是不安全的程式碼,但是能提升很多效能
本文程式碼放在 github 歡迎小夥伴訪問
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含連結:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。如有任何疑問,請與我聯絡。