.netには、intをバイト配列に変換するために使用する何らかの簡単な変換方法があると思いましたか?私はクイック検索を行いましたが、すべてのソリューションは、「古き良き時代」のように、一度に1バイトずつビットマスキング/シフトしています。 ToByteArray()メソッドはどこにもありませんか?
byte[] bytes = BitConverter.GetBytes(i);
ただし、mightを確認したいことにも注意してくださいBitConverter.IsLittleEndian
それがどの方向に現れるかを見るために!
これを行っている場合繰り返しいずれかのシフト操作(>>
/<<
)、またはunsafe
コードを使用します。シフト操作()は、プラットフォームのエンディアンの影響を受けないという利点があります。 you always期待する順序でバイトを取得します。
マークの答えはもちろん正しい答えです。しかし、彼は代替としてシフト演算子と安全でないコードに言及しました。あまり一般的ではない代替案を共有したいと思います。 Explicit
レイアウトで構造体を使用します。これは、原則としてC/C++ union
と似ています。
Int32データ型のコンポーネントバイトを取得するために使用できる構造体の例を次に示します。ナイスなことは、2つの方法であり、バイト値を操作してIntに対する効果を確認できることです。
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct Int32Converter
{
[FieldOffset(0)] public int Value;
[FieldOffset(0)] public byte Byte1;
[FieldOffset(1)] public byte Byte2;
[FieldOffset(2)] public byte Byte3;
[FieldOffset(3)] public byte Byte4;
public Int32Converter(int value)
{
Byte1 = Byte2 = Byte3 = Byte4 = 0;
Value = value;
}
public static implicit operator Int32(Int32Converter value)
{
return value.Value;
}
public static implicit operator Int32Converter(int value)
{
return new Int32Converter(value);
}
}
上記は次のように使用できるようになりました
Int32Converter i32 = 256;
Console.WriteLine(i32.Byte1);
Console.WriteLine(i32.Byte2);
Console.WriteLine(i32.Byte3);
Console.WriteLine(i32.Byte4);
i32.Byte2 = 2;
Console.WriteLine(i32.Value);
もちろん、不変性の警察は最後の可能性について興奮していないかもしれません:)
これはOTかもしれませんが、多くのプリミティブ型またはPOD構造をシリアル化する場合は、 Googleの.Net用プロトコルバッファー が役立つ場合があります。上記で取り上げた@Marcの問題、その他の便利な機能。
Googleからここに来た場合
古い質問に対する別の答えは、インデックスオフセットを使用してプリミティブデータ型をbyte []に直接書き込むためのツールを備えたJohn Skeetのライブラリを参照しています。パフォーマンスが必要な場合は、BitConverter
よりはるかに優れています。
ソースをダウンロードして、MiscUtil.Conversion
名前空間。 EndianBitConverter.cs
はすべてを処理します。
ここでの回答のほとんどは「UnSafe」またはLittleEndianセーフではありません。BitConverterはLittleEndianセーフではありません。したがって、 here (PZahraの投稿を参照) BitConverter.IsLittleEndian == trueの場合にバイト配列を逆方向に読み取るだけの安全なバージョン
void Main(){
Console.WriteLine(BitConverter.IsLittleEndian);
byte[] bytes = BitConverter.GetBytes(0xdcbaabcdfffe1608);
//Console.WriteLine(bytes);
string hexStr = ByteArrayToHex(bytes);
Console.WriteLine(hexStr);
}
public static string ByteArrayToHex(byte[] data)
{
char[] c = new char[data.Length * 2];
byte b;
if(BitConverter.IsLittleEndian)
{
//read the byte array in reverse
for (int y = data.Length -1, x = 0; y >= 0; --y, ++x)
{
b = ((byte)(data[y] >> 4));
c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(data[y] & 0xF));
c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
}
else
{
for (int y = 0, x = 0; y < data.Length; ++y, ++x)
{
b = ((byte)(data[y] >> 4));
c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(data[y] & 0xF));
c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
}
return String.Concat("0x",new string(c));
}
これを返します:
True
0xDCBAABCDFFFE1608
これは、バイト配列に入った正確な16進数です。