Я думал, что у .NET есть какой-то простой метод преобразования, который можно использовать для преобразования int в массив байтов? Я сделал быстрый поиск, и все решения бит маскируют/сдвигают один байт за раз, например "хорошие дни". Нет ли метода ToByteArray() где-нибудь?
Int в байтовый массив
Ответ 1
byte[] bytes = BitConverter.GetBytes(i);
хотя обратите внимание также на то, что вы можете проверить BitConverter.IsLittleEndian
, чтобы увидеть, какой путь будет отображаться!
Обратите внимание, что если вы делаете это повторно, вы можете избежать всех этих короткоживущих распределений массивов, написав их самостоятельно с помощью операций сдвига (>>
/<<
) или с помощью кода unsafe
. Операции переключения также имеют то преимущество, что они не подвержены влиянию вашей платформы; вы всегда получаете байты в том порядке, в котором вы их ожидаете.
Ответ 2
Ответ Marc - это, конечно, правильный ответ. Но поскольку он упомянул операторы сдвига и небезопасный код в качестве альтернативы. Я хотел бы поделиться менее распространенной альтернативой. Использование структуры с макетом Explicit
. В принципе это аналогично C/С++ union
.
Вот пример структуры, которая может использоваться для доступа к байтам компонента типа данных Int32, и хорошо, что это два пути, вы можете манипулировать байтовыми значениями и видеть влияние на 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);
Конечно, полиция неизменности может быть не в восторге от последней возможности:)
Ответ 3
Это может быть OT, но если вы сериализуете множество примитивных типов или структур POD, Буферы протокола Google для .Net могут быть полезны для вы. Это относится к проблеме endianness @Marc, поднятой выше, среди других полезных функций.
Ответ 4
Если вы пришли сюда из Google
Альтернативный ответ на старый вопрос относится к библиотеке Джона Скита, в которой есть инструменты, позволяющие записывать примитивные типы данных непосредственно в байт [] со смещением индекса. Намного лучше, чем BitConverter
, если вам нужна производительность.
Старые темы обсуждают эту проблему здесь
Просто скачайте исходный код и посмотрите на пространство имен MiscUtil.Conversion
. EndianBitConverter.cs
обрабатывает все для вас.
Ответ 5
Большинство ответов здесь либо "UnSafe", либо не LittleEndian safe. BitConverter не является безопасным для LittleEndian. Поэтому, опираясь на пример в здесь (см. Сообщение от PZahra), я сделал безопасную версию LittleEndian просто, читая массив байтов в обратном порядке, когда 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
который является точным шестнадцатеричным, который попал в массив байтов.