2009-08-17 7 views

Odpowiedz

17

BitConverter to prawdopodobnie Twój przyjaciel.

Powoduje to jednak, że generowana jest nowa tablica bajtowa nowa. Nie pozwala też określić dokładności. Mam klasę EndianBitConverter w MiscUtil, która ma metody konwertowania typów pierwotnych przez skopiowanie danych bezpośrednio do istniejącej tablicy bajtów.

Na przykład:

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

Wow, codziennie uczysz się czegoś nowego :) Nawet nie wiedziałeś, że istnieje! – Gareth

+1

Uzgodnione, lepsze niż podejście zmiany, ponieważ nie trzeba myśleć o endian-ness. (Chyba że musi to zmienić). –

8

zrobić to jak BinaryWriter robi:

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

(oczywiście to skopiuje int w ciągu pierwszych 4 bajty tablicy)

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; 
} 
1

Bufor.BlockCopy (intArray, 0, byteArray, 0, 4 * intArray.Length)

Kopiuje dane między dwiema tablicami. Ostatni argument to ilość danych do skopiowania w bajtach.

6

Istnieje wiele różnych sposobów, aby to zrobić, ale aby było ładniej, użyjmy nowej funkcji rozszerzeń C#:.

Liczba całkowita z 32-bitowej odmiany zajmuje 4 bajty, więc zajmie 4 miejsca w bajcie []. Jak rozbić liczbę całkowitą w jej 4 bajtach składowych? Możesz to zrobić za pomocą operatora manipulacji bitami >>. Ten operator przesuwa bity w liczbie całkowitej o określoną liczbę bitów. Np

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

Ponieważ bajt wynosi 8 bitów, jeśli przesunięcie liczbę całkowitą od 8 bitów musimy nową drugą wartość bajtu całkowitą w położeniu skrajnym prawym bitów

10399 >> 8 = 00000000 00101000 

Zawiadomienie jak drugi bajt nie jest pierwszym bajtem, a pozostałe bity zostały zastąpione przez 0.

Możemy użyć tej sztuczki, aby przesunąć bajty na pierwszą pozycję, a następnie wymusić rzutowanie na bajt, co spowoduje odrzucenie 3 inne bajty i pozostawi nam ostatnią wartość bajtów:

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

Tak, przy użyciu tej techniki dla 4 bajty dadzą nam dostęp do każdego z nich i będziemy kopiować je w tablicy docelowej, który został przekazany do naszego nowego sposobu 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 
    } 
} 

Należy zauważyć, że moglibyśmy skopiować bajty w odwrotnej kolejności, czyli do twojej implementacji.

Funkcja rozszerzenie pozwoli Ci uzyskać dostęp do nowej funkcji jako członek klasy integer:

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

postaram się podsumować niektóre z poprzednich odpowiedzi do stworzenia czegoś nowego

Krok 1. Jak Jon Skeet powiedział wcześniej:

BitConverter jest całkiem możliwe, twój przyjaciel.

Powoduje to jednak, że generowana jest nowa tablica bajtowa nowa.

Krok 2. można znaleźć kod źródłowy BitConverter.GetBytes (int value) Metoda:

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

Krok 3. Korzystanie wyobraźnię i zmieniając kilka linii w kodzie od krok 2 więc może zapisać dane do istniejącej tablicy:

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

uogólniając ADB Exquisit odpowiedź:

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)); 
     } 
    } 
} 
Powiązane problemy