2009-08-17 8 views

答えて

17

BitConverterはおそらくあなたの友人です。

ただし、通常はの新しいバイト配列が返されます。また、エンディアンを指定することもできません。私はMiscUtilEndianBitConverterクラスを持っています。このクラスには、データを既存のバイト配列に直接コピーすることによってプリミティブ型を変換するメソッドがあります。

// Copy the bytes from the integer "value" into a byte array 
// (buffer) starting at index 5 
EndianBitConverter.Little.CopyBytes(value, buffer, 5); 
+0

うわー、あなたは毎日何か新しいことを学びます:)存在していたことさえ知りませんでした! – Gareth

+1

あなたがエンディアンを考える必要がないので、シフトアプローチよりも合意しました。 (もちろん、彼はそれを変更する必要がない限り)。 –

8

はBinaryWriterはそれをしないどのようにそれを実行します:例えば

buffer[0] = (byte) value; 
buffer[1] = (byte) (value >> 8); 
buffer[2] = (byte) (value >> 0x10); 
buffer[3] = (byte) (value >> 0x18); 

0
byte[] bytes = new byte[listOfInts.Count * sizeof(int)]; 
int pos = 0; 
foreach(int i in listOfInts) 
{ 
    byte[] b = BitConverter.GetBytes(i); 
    b.CopyTo(bytes, pos); 
    pos += b.Length; 
} 
(もちろんこれは配列の最初の4バイトにint型をコピーします)
1

Buffer.BlockCopy(intArray、0、byteArray、0、4 * intArray.Length)

2つのアレイ間でデータをコピーします。最後の引数は、コピーするデータ量(バイト単位)です。

6

これにはさまざまな方法がありますが、それをより良くするために、c#:extensionsの新機能を使用できます。

32ビットのバラエティの整数は4バイトを取るため、バイト[]内の4つのスポットを占有します。どのように4つの構成バイトの整数を分割しますか?ビット操作演算子>>を使用して実行できます。その演算子は、指定されたビット数だけ整数のビットをシフトします。例えば:

integer = 10399 
binary = 00101000 10011111 
10399 >> 1 == 0010100 01001111 each bit shifted by 1 

バイトは8ビットであるので、我々は8ビット整数をシフトする場合、我々は最も右のビット位置に

10399 >> 8 = 00000000 00101000 

注意を整数の新たな第2バイト値を持っていますどのように2番目のバイトが最初のバイトではなく、残りのビットが0に置き換えられたかを示します。

このトリックを使用してバイトを最初の位置に移動し、キャストをバイトに強制します。 3つの他のバイトと最後のバイト値を残します:

(byte)(10399 >> 8) == 0010100 

ので、4バイトのためにこの技術を使用することは、私たちにそれぞれ1へのアクセス権を与えると、私たちは私たちの新しいCopyToByteArrayメソッドに渡されたコピー先の配列にコピーします:

public static class Int32Extension 
{ 
    public static void CopyToByteArray(this int source, byte[] destination, int offset) 
    { 
     if (destination == null) 
      throw new ArgumentException("Destination array cannot be null"); 

     // check if there is enough space for all the 4 bytes we will copy 
     if (destination.Length < offset + 4) 
      throw new ArgumentException("Not enough room in the destination array"); 

     destination[offset] = (byte)(source >> 24); // fourth byte 
     destination[offset+1] = (byte)(source >> 16); // third byte 
     destination[offset+2] = (byte)(source >> 8); // second byte 
     destination[offset+3] = (byte)source; // last byte is already in proper position 
    } 
} 

。なお、逆の順序でバイトをコピーしていた可能性があります。これは実装によって異なります。

拡張機能を使用すると、整数クラスのメンバーとして新しい機能にアクセスできるようになります:

int something = 20; 
byte[] array = new byte[4]; 
something.CopyToByteArray(array,0); 
6

が、私は何か新しいものを作るために、以前の回答の一部を要約してみます

BitConverterは恐らくあなたの友達です:Jon Skeetとしてステップ1は前に述べました。

ただし、通常はの新しいバイト配列が返されます。

あなたはBitConverter.GetBytesのソースコード(int値)メソッドを見つけることができます。2.ステップ:

public static unsafe byte[] GetBytes(int value) 
{ 
    byte[] numArray = new byte[4]; 
    fixed (byte* numPtr = numArray) 
     *(int*) numPtr = value; 
    return numArray; 
} 

ステップ3.想像力を使用してから、コード内のいくつかの行を変更ステップ2それは、既存のアレイにデータを保存することができます:

public static unsafe byte[] GetBytes(int value, int buffer[], int offset) 
{ 
    // Here should be a range check. For example: 
    // if (offset > buffer.Length + sizeof(int)) throw new IndexOutOfRangeException(); 

    fixed (byte* numPtr = &buffer[offset]) 
     *(int*) numPtr = value; 
} 
0

一般化ADBのエクスクイジットの答え:

public static class Int32Extension 
{ 

    /// <summary> 
    /// Copies an int to a byte array: Byte order and sift order are inverted. 
    /// </summary> 
    /// <param name="source">The integer to convert.</param> 
    /// <param name="destination">An arbitrary array of bytes.</param> 
    /// <param name="offset">Offset into the desination array.</param> 
    public static void CopyToByteArray(this int source, byte[] destination, int offset) 
    { 
     if (destination == null) 
      throw new ArgumentException("Destination array cannot be null"); 

     // check if there is enough space for all the 4 bytes we will copy 
     if (destination.Length < offset + sizeof(int)) 
      throw new ArgumentException("Not enough room in the destination array"); 

     for (int i = 0, j = sizeof(int) - 1; i < sizeof(int); i++, --j) { 
      destination[offset + i] = (byte) (source >> (8 * j)); 
     } 
    } 

    /// <summary> 
    /// Copies an int to a to byte array Little Endian: Byte order and sift order are the same. 
    /// </summary> 
    /// <param name="source">The integer to convert.</param> 
    /// <param name="destination">An arbitrary array of bytes.</param> 
    /// <param name="offset">Offset into the desination array.</param> 
    public static void CopyToByteArrayLE(this int source, byte[] destination, int offset) 
    { 
     if (destination == null) 
      throw new ArgumentException("Destination array cannot be null"); 

     // check if there is enough space for all the 4 bytes we will copy 
     if (destination.Length < offset + sizeof(int)) 
      throw new ArgumentException("Not enough room in the destination array"); 

     for (int i = 0, j = 0; i < sizeof(int); i++, j++) { 
      destination[offset + i] = (byte) (source >> (8 * j)); 
     } 
    } 
} 
関連する問題