2016-12-19 26 views
2

我有一個由Byte數組表示的Int32數組(每4個字節爲1個Int32),我想將它們轉換爲Int32數組(長度爲Byte。長度/ 4)。 我這裏是我想要的東西:如何將字節數組表示的Int32數組轉換爲Int32數組中的C#

//byte[] buffer; 
for (int i=0; i<buffer.Length; i+=4) 
{ 
    Int32 temp0 = BitConverter.ToInt32(buffer, i); 
    temp0 += 10; 
    byte[] temp1 = BitConverter.GetBytes(temp0); 
    for (int j=0;j<4;j++) 
    { 
     buffer[i + j] = temp1[j]; 
    } 
} 

但我不希望複製他們,我只是希望能夠告訴編譯器,它的Int32數組,而不是一個字節數組(以後來的操作)。

我看着這個How to Convert a byte array into an int array,但它將每個字節轉換爲Int32,並且我想將每個字節轉換爲Int32。 我也想這樣做,而不是將其複製到另一個陣列中以獲得性能。

(我們可以假設硬件是endianness本地,little endian表示小端系統)。

+2

聽起來像是一個不安全的指針和指針 – pm100

+0

[這裏](https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs,1618fc20415532f2)是['BitConverter.ToInt32(byte [ ],Int32)'](https://msdn.microsoft.com/en-us/library/system.bitconverter.toint32(v = vs.110).aspx);我*認爲*此代碼:'固定(字節* pbyte =&值[startIndex]){如果(startIndex%4 == 0){/ /數據對齊返回*((int *)pbyte); }'意味着它只是在對齊時將4個字節轉換爲int32,它不*轉換,因此應該是快速的。有人可以驗證嗎? – Quantic

+0

@ pm100你能寫出不安全的代碼嗎?我嘗試過,但我得到了各種錯誤:( – pio

回答

3

沒有直接的方式來轉換它們而不復制它們。你可以編寫一個linq查詢來返回字節整數,但不會讓你操縱它們。

一種方式來實現你想要的可能是把這個包在自己的類:從您byte陣列

public class IntArrayOverBytes 
{ 
    private readonly byte[] bytes; 
    public IntArrayOverBytes(byte[] bytes) 
    { 
     this.bytes = bytes; 
    } 

    public int this[int index] 
    { 
     get { return BitConverter.ToInt32(bytes, index * 4); } 
     set { Array.Copy(BitConverter.GetBytes(value), 0, bytes, index * 4, 4); } 
    } 
} 

有了這個類,你可以閱讀int值,並將其寫回:

IntArrayOverBytes intArray = new IntArrayOverBytes(bytes); 
intArray[5] = 2016; 
Console.WriteLine(intArray[5]); 

對於完整的Array類似的功能,你需要添加更多的代碼。例如,實現IEnumerable<int>可能是有用的:

public int Length => bytes.Length/4; 
public IEnumerator<int> GetEnumerator() 
{ 
    for(int i=0; i<Length; i++) yield return this[i]; 
} 
+0

你的代碼是沒有doudbt更好,比我的可讀性更強,但我仍然認爲有一種方法可以在沒有複製的情況下投射,畢竟內存已經設置爲Int32,而我們只是需要編譯器來了解它,我真的關心這個應用程序的性能。 – pio

+0

@pio所以我想你會需要評論中提到的其中一種「不安全」的方式,但我沒有經歷過。 –

+0

@pio但請注意我的代碼不復制數組,只複製數組的引用。當然它會「複製」你訪問的值。 –

1

這裏是不安全的版本之一(需要Allow unsafe code在項目生成屬性選中):

byte[] buffer = { 255,255,255,255, 255,255,255,127 }; // little endian { -1, int.MaxValue } 

unsafe 
{ 
    fixed (byte* bytePtr = buffer) // or = &buffer[0] 
    { 
     for (int* intPtr = (int*)bytePtr; intPtr < bytePtr + buffer.Length; intPtr++) 
     { 
      *intPtr += 10; //intPtr is the address, and *intPtr is the value at that address 
     } 
    } 
} 

Debug.Print(string.Join(", ", buffer)); //"9, 0, 0, 0, 9, 0, 0, 128" { 9, int.MinValue + 9 } 

fixed需要得到數組的地址,並防止垃圾收集器將陣列重新定位到不同的內存位置。 bytePtr + buffer.Lengthbuffer數組中最後一個元素之後的內存地址。給intPtr地址加1會使它移動4個字節。

我的猜測是不安全的版本比安全的BitConverter版本快不到2倍,所以我認爲風險是不值得的。我想你可以從my previous answer的建議中獲得更好的表現。

+0

Thx爲您提供幫助! 但我需要傳遞數組進一步處理(例如一個函數),如果我只是通過int *我不能把它當作int [](轉換出錯)。 我開始放棄在C#上,Ints數組已經在int32的正確位置的內存中,唯一需要的是告訴編譯器將它們當作Int數組而不是字節數組。 – pio

相關問題