2011-05-03 14 views
8

Siguiendo el consejo proporcionado en la pregunta https://stackoverflow.com/questions/1738244/what-is-the-java-equivalent-of-net-bitconverter He comenzado a implementar mi propia BitConverter para Java, pero no estoy obteniendo resultados equivalentes.BitConverter para Java

¿Podría alguien por favor guiarme sobre lo que podría estar haciendo incorrectamente?

public static byte[] GetBytes(Integer value) { 
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 
    DataOutputStream stream = new DataOutputStream(byteStream); 
    try { 
     stream.writeInt(value); 
    } catch (IOException e) { 
     return new byte[4]; 
    } 
    return byteStream.toByteArray(); 
} 

byte[] result = BitConverter.GetBytes(1234); //JAVA: [0, 0, 4, -46] 
byte[] result = BitConverter.GetBytes(1234); //C#: [210, 4, 0, 0] 

Respuesta

8

Eso es sólo Endianness (-46 y 210 se debe a que de bytes de Java firmados, pero eso es sólo una cosa de la interfaz de usuario). Invierta el contenido de la matriz o use las operaciones de cambio para escribir el int.

Nota: la capacidad de endianancia que emite .NET depende de la plataforma. Sugeriría usar CONOCIMIENTO CONOCIDO en ambos casos; muy probablemente usando las operaciones de cambio de ambos. O tal vez una idea mejor: simplemente use un formato de serialización independiente de la plataforma previamente enlatado (por ejemplo: búferes de protocolo, que tiene un buen soporte en Java y .NET/C#).

Por ejemplo; si estuviera escribiendo un int value a un byte[] buffer (a partir de offset), puede ser que utilice:

buffer[offset++] = (byte)value; 
buffer[offset++] = (byte)(value>>8); 
buffer[offset++] = (byte)(value>>16); 
buffer[offset++] = (byte)(value>>24); 

esto está garantizado ascendente hacia la izquierda, y el código similar debería funcionar en cualquier marco.

+0

lo que está fuera ¿valor ajustado? – gpa

+0

@gpa sin importar cuánto haya leído hasta ahora –

4

El C# BitConverter utilizará el orden de bits de la achitecture subyacente. En la mayoría de los entornos, será little-endian (como lo es en su caso). Sin embargo, Java DataOutputStream siempre escribirá en big-endian ("el modo portátil"). Necesitará verificar el endianness de la máquina y escribir en consecuencia si desea hacer coincidir el comportamiento.

Además, los bytes en java están firmados por lo que el resultado es solo una diferencia estética. La representación de bits es la misma, por lo que no debe preocuparse por eso.

Para comprobar el orden de bits de su máquina, utilice el método java.nio.ByteOrder.nativeOrder(). Luego use java.nio.ByteBuffer en su lugar donde puede especificar el byte order() y escribir los datos.

A continuación, podría poner en práctica su método como este:

public static byte[] GetBytes(int value) 
{ 
    ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()); 
    buffer.putInt(value); 
    return buffer.array(); 
} 
1

Sobre la base de la respuesta de Jeff, se puede utilizar una sola ByteBuffer para convertir hacia y desde int y byte[]. Aquí está el código que puede caer en una clase para convertir a/de Little Endian:

ByteBuffer _intShifter = ByteBuffer.allocate(Integer.SIZE/Byte.SIZE) 
            .order(ByteOrder.LITTLE_ENDIAN); 

public byte[] intToByte(int value) { 
    _intShifter.clear(); 
    _intShifter.putInt(value);  
    return _intShifter.array(); 
} 

public int byteToInt(byte[] data) 
{ 
    _intShifter.clear(); 
    _intShifter.put(data, 0, Integer.SIZE/Byte.SIZE); 
    _intShifter.flip(); 
    return _intShifter.getInt(); 
} 
1

si alguno need..C cuerpo # a Java BitConverter.ToInt32

public static int toInt32_2(byte[] bytes, int index) 
     { 
      int a = (int)((int)(0xff & bytes[index]) << 32 | (int)(0xff & bytes[index + 1]) << 40 | (int)(0xff & bytes[index + 2]) << 48 | (int)(0xff & bytes[index + 3]) << 56); 
      // int a = (int)((int)(0xff & bytes[index]) << 56 | (int)(0xff & bytes[index + 1]) << 48 | (int)(0xff & bytes[index + 2]) << 40 | (int)(0xff & bytes[index + 3]) << 32); 
      //Array.Resize; 
      return a; 
     } 

también Int16

public static short toInt16(byte[] bytes, int index) //throws Exception 
    { 
     return (short)((bytes[index + 1] & 0xFF) | ((bytes[index] & 0xFF) << 0)); 
     //return (short)(
     //  (0xff & bytes[index]) << 8 | 
     //    (0xff & bytes[index + 1]) << 0 
     //); 
    } 

BitConverter.getBytes

public static byte[] GetBytesU16(long value) 
{ 

    ByteBuffer buffer = ByteBuffer.allocate(8).order(ByteOrder.nativeOrder()); 
    buffer.putLong(value); 
    return buffer.array(); 
}