2012-03-21 13 views
30

Come dice il titolo, c'è una libreria Scala che esporta le funzioni per convertire, preferibilmente fluentemente, una matrice di byte in un Int, in un Lunga o doppia?Libreria Scala per convertire numeri (Int, Long, Double) in/da Array [Byte]

Ho bisogno di qualcosa compatibile con 2.9.1 e FOSS.

Se sapete esattamente di cosa ho bisogno e dove trovarlo, basterà una linea per SBT e una linea per un esempio! :)

Se c'è alcuna cosa come quello che sto cercando, la cosa più vicina in Java funziona anche ...

risposta

40

È possibile utilizzare Java NIO's ByteBuffer:

import java.nio.ByteBuffer 

ByteBuffer.wrap(Array[Byte](1, 2, 3, 4)).getInt 
ByteBuffer.wrap(Array[Byte](1, 2, 3, 4, 5, 6, 7, 8)).getDouble 
ByteBuffer.wrap(Array[Byte](1, 2, 3, 4, 5, 6, 7, 8)).getLong 

Nessun dipendenze extra richieste .

16

di Java nio.ByteBuffer è la strada da percorrere per il momento:

val bb = java.nio.ByteBuffer.allocate(4) 
val i = 5 
bb.putInt(i) 
bb.flip // now can read instead of writing 
val j = bb.getInt 
bb.clear // ready to go again 

È possibile anche put array di byte, ecc

Tenete a mente la piccola cosa/big-endian. bb.order(java.nio.ByteOrder.nativeOrder) è probabilmente quello che vuoi.

2

Per Double < -> ByteArray, è possibile utilizzare java.lang.Double.doubleToLongBits e java.lang.Double.longBitsToDouble.

import java.lang.Double 

def doubleToByteArray(x: Double) = { 
    val l = java.lang.Double.doubleToLongBits(x) 
    val a = Array.fill(8)(0.toByte) 
    for (i <- 0 to 7) a(i) = ((l >> ((7 - i) * 8)) & 0xff).toByte 
    a 
} 

def byteArrayToDouble(x: Array[scala.Byte]) = { 
    var i = 0 
    var res = 0.toLong 
    for (i <- 0 to 7) { 
     res += ((x(i) & 0xff).toLong << ((7 - i) * 8)) 
    } 
    java.lang.Double.longBitsToDouble(res) 
} 

scala> val x = doubleToByteArray(12.34) 
x: Array[Byte] = Array(64, 40, -82, 20, 122, -31, 71, -82) 

scala> val y = byteArrayToDouble(x) 
y: Double = 12.34 

O ByteBuffer può essere utilizzato:

import java.nio.ByteBuffer 
def doubleToByteArray(x: Double) = { 
    val l = java.lang.Double.doubleToLongBits(x) 
    ByteBuffer.allocate(8).putLong(l).array() 
} 

def byteArrayToDouble(x:Array[Byte]) = ByteBuffer.wrap(x).getDouble 
18

È inoltre possibile utilizzare BigInt dalla libreria standard Scala.

import scala.math.BigInt 
val bytearray = BigInt(1337).toByteArray 
val int = BigInt(bytearray) 
+2

Perché nessuno ha votato la risposta più breve fino a me. Soluzione Scala pura! Risposta IMHO migliore – yerlilbilgin

+1

Si noti che si dovrebbe prestare attenzione al riempimento quando si usa BigInt per convertire i tipi interi in array di byte, perché BigInt (1) .toByteArray == Array (1), non (Array (0,0,0,1)) –