2010-11-28 11 views
44

Quiero cambiar los valores en la matriz de bytes para poner un valor de indicación de fecha y hora larga en las MSB. ¿Puede alguien decirme cuál es la mejor manera de hacerlo? No quiero insertar valores bit por bit, que creo que es muy ineficiente.Convierta una matriz de longitud en bytes y agréguelo a otra matriz

long time = System.currentTimeMillis(); 
Long timeStamp = new Long(time); 
byte[] bArray = new byte[128]; 

Lo que yo quiero es algo así como:

byte[0-63] = timeStamp.byteValue(); 

Es algo como esto sea posible. ¿Cuál es la mejor manera de editar/insertar valores en esta matriz de bytes? dado que el byte es primitivo, ¿no creo que hay algunas implementaciones directas que puedo utilizar?

Editar:
Parece que es más rápido que System.currentTimeMillis()Calendar.getTimeInMillis(), por lo que reemplazar el código anterior por it.Please corrígeme si equivocado.

+0

esto era útil: http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java – TacB0sS

+0

Creo que tienen los índices cuentan incorrecto, verifique esta pregunta fuera: http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java – TacB0sS

Respuesta

121

Hay varias formas de hacerlo:

  • Utilice A (mejor opción - concisa y fácil de leer) ByteBuffer:

    byte[] bytes = ByteBuffer.allocate(Long.SIZE/Byte.SIZE).putLong(someLong).array(); 
    
  • También puede utilizar DataOutputStream (más detallado) :

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    DataOutputStream dos = new DataOutputStream(baos); 
    dos.writeLong(someLong); 
    dos.close(); 
    byte[] longBytes = baos.toByteArray(); 
    
  • Por último, puede hacer este manu aliada (tomado de la LongSerializer en el código de Hector) (más difícil de leer):

    byte[] b = new byte[8]; 
    for (int i = 0; i < size; ++i) { 
        b[i] = (byte) (l >> (size - i - 1 << 3)); 
    } 
    

A continuación, puede añadir estos bytes a su matriz existente por un bucle simple:

// change this, if you want your long to start from 
// a different position in the array 
int start = 0; 
for (int i = 0; i < longBytes.length; i ++) { 
    bytes[start + i] = longBytes[i]; 
} 
+0

gracias Bozho. Creo que esto es lo que estaba buscando. Creo que el primer método sería más rápido que el posterior. Solo me preocupa el impacto en el rendimiento del uso de ByteBuffer en lugar de byte array. Este enlace habla más sobre el rendimiento en ned bytebuffer lib: http://jroller.com/cpurdy/date/20040405#raw_nio_performance; Además, si el impacto no es enorme, ¿puedo usar ByteBuffer en lugar de una matriz de bytes? – codeObserver

+0

Use 'ByteBuffer'. Dudo que cause ningún problema. – Bozho

+4

Descubrí que tenía que establecer el orden en ByteByffer como tal, de lo contrario, los bytes eran el orden inverso al que esperaba byte [] bytes = ByteBuffer.allocate (8) .order (ByteOrder.LITTLE_ENDIAN) .putLong (bits) .Array(); –

0

No parece que pueda cortar una matriz de bytes para insertar algo en un subconjunto sin hacerlo byte por byte. Mira Grab a segment of an array in Java without creating a new array on heap. Básicamente, lo que haría sería establecer una matriz de 64 bytes y establecer el tiempo para ello, luego agregarle una matriz de 64 bytes en blanco. O simplemente haz byte por byte.

0

soy actualizando esta publicación porque acabo de anunciar una versión preliminar de una biblioteca que convertirá largos en matrices de bytes (y viceversa). La biblioteca es muy pequeña y convertirá cualquier primitiva Java en una matriz de bytes.

http://rschilling.wordpress.com/2013/09/26/pre-release-announcement-pend-oreille/ http://code.google.com/p/pend-oreille/

Si lo usa puede hacer cosas como convertir matrices largas a matrices de bytes:

Double[] doubles = new Double[1000]; 
for (int i = 2; i < 1002; i++) { 
    doubles[i - 2] = (double) i; 
} 

byte[] resultBytes1 = (byte[]) new PrimitiveHelper(PrimitiveUtil.unbox(doubles)) 
     .asType(byte[].class); 

También puede convertir un solo valor a largo también.

byte[] resultBytes1 = (byte[]) new PrimitiveHelper(1000l) 
     .asType(byte[].class); 

Siéntase libre de aportar sus comentarios.

actualización el 4 de octubre de 2013: que ha salido ahora a la producción de la biblioteca http://rschilling.wordpress.com/2013/10/04/pend-oreille-official-1-0-release/

17

Si usted quiere conseguir realmente bajo el capó ...

public byte[] longToByteArray(long value) { 
    return new byte[] { 
     (byte) (value >> 56), 
     (byte) (value >> 48), 
     (byte) (value >> 40), 
     (byte) (value >> 32), 
     (byte) (value >> 24), 
     (byte) (value >> 16), 
     (byte) (value >> 8), 
     (byte) value 
    }; 
} 
3

Para mí y ByteBuffer otros utils son costosos desde la perspectiva del tiempo. Aquí hay 2 métodos que se pueden utilizar:

// primer método (que está utilizando el segundo método), es devolver la matriz asignado y cumplió

public byte[] longToByteArray(long value) 
{ 
     byte[] array = new byte[8]; 

     longToByteArray(value,array,0); 
     return array; 
} 

// Este método es útil si ya tiene asignado el búfer y desea escribir el largo de una ubicación específica en el conjunto.

public void longToByteArray(long value, byte[] array, int startFrom) 
{ 
    for (int i=7; i>=0; i--) 
    { 
     array[startFrom+7-i] = (byte) (value >> i*8); 
    } 
} 
Cuestiones relacionadas