如何在java中将Long转换为byte[]并返回

如何在java中将Long转换为byte[]并返回,java,type-conversion,byte,long-integer,Java,Type Conversion,Byte,Long Integer,如何将long转换为byte[]并返回Java 我正在尝试将long转换为byte[],以便能够通过TCP连接发送byte[]。另一方面,我想把字节[]转换回双精度 public byte[] longToBytes(long x) { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(x); return buffer.array(); } public long bytesToLo

如何将
long
转换为
byte[]
并返回Java

我正在尝试将
long
转换为
byte[]
,以便能够通过TCP连接发送
byte[]
。另一方面,我想把
字节[]
转换回
双精度

public byte[] longToBytes(long x) {
    ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
    buffer.putLong(x);
    return buffer.array();
}

public long bytesToLong(byte[] bytes) {
    ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
    buffer.put(bytes);
    buffer.flip();//need flip 
    return buffer.getLong();
}
或封装在类中以避免重复创建ByteBuffers:

public class ByteUtils {
    private static ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);    

    public static byte[] longToBytes(long x) {
        buffer.putLong(0, x);
        return buffer.array();
    }

    public static long bytesToLong(byte[] bytes) {
        buffer.put(bytes, 0, bytes.length);
        buffer.flip();//need flip 
        return buffer.getLong();
    }
}


因为这是如此流行,我只想说,我认为你最好使用像番石榴在绝大多数情况下图书馆。如果您对库有一些奇怪的反对意见,您应该首先考虑本地java解决方案。我认为我的答案的主要意义在于,你不必担心系统的终结性。

为什么需要字节[]?为什么不直接将它写入套接字呢

我假设您指的是long而不是long,后者需要允许空值

DataOutputStream dos = new DataOutputStream(
     new BufferedOutputStream(socket.getOutputStream()));
dos.writeLong(longValue);

DataInputStream dis = new DataInputStream(
     new BufferedInputStream(socket.getInputStream()));
long longValue = dis.readLong();

如果您已经在使用
OutputStream
写入套接字,那么这可能是一个很好的选择。以下是一个例子:

// Assumes you are currently working with a SocketOutputStream.

SocketOutputStream outputStream = ...
long longValue = ...

DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

dataOutputStream.writeLong(longValue);
dataOutputStream.flush();
对于
short
int
float
等,也有类似的方法。然后,您可以在接收端使用。

只需将long写入具有底层的a即可。从ByteArrayOutputStream,您可以通过以下方式获得字节数组:

相应地适用于其他原语

提示:对于TCP,您不需要手动使用字节[]。您将使用
套接字及其流

OutputStream os=socket.getOutputStream(); 
DataOutputStream dos=new DataOutputStream(os);
dos.writeLong(l);
//etc ..
相反。

公共静态长字节testolong(字节[]字节){
 public static long bytesToLong(byte[] bytes) {
        if (bytes.length > 8) {
            throw new IllegalMethodParameterException("byte should not be more than 8 bytes");

        }
        long r = 0;
        for (int i = 0; i < bytes.length; i++) {
            r = r << 8;
            r += bytes[i];
        }

        return r;
    }



public static byte[] longToBytes(long l) {
        ArrayList<Byte> bytes = new ArrayList<Byte>();
        while (l != 0) {
            bytes.add((byte) (l % (0xff + 1)));
            l = l >> 8;
        }
        byte[] bytesp = new byte[bytes.size()];
        for (int i = bytes.size() - 1, j = 0; i >= 0; i--, j++) {
            bytesp[j] = bytes.get(i);
        }
        return bytesp;
    }
如果(bytes.length>8){ 抛出新的IllegalMethodParameterException(“字节不应超过8字节”); } 长r=0; for(int i=0;i8; } byte[]bytesp=新字节[bytes.size()]; 对于(int i=bytes.size()-1,j=0;i>=0;i--,j++){ bytesp[j]=bytes.get(i); } 返回bytesp; }
您可以在org.apache.hadoop.hbase.util.Bytes中使用该实现

源代码如下:

寻找toLong和toBytes方法

我相信软件许可证允许您获取部分代码并使用它,但请验证。

您可以从中使用

例如:

byte[] bytes = Longs.toByteArray(12345L);

如果您正在寻找一个快速展开的版本,假设一个名为“b”的字节数组的长度为8:

字节[]->长

long l = ((long) b[7] << 56)
       | ((long) b[6] & 0xff) << 48
       | ((long) b[5] & 0xff) << 40
       | ((long) b[4] & 0xff) << 32
       | ((long) b[3] & 0xff) << 24
       | ((long) b[2] & 0xff) << 16
       | ((long) b[1] & 0xff) << 8
       | ((long) b[0] & 0xff);

我对ByteBuffer方法进行了简单的位操作测试,但后者的速度要快得多

public static byte[] longToBytes(long l) {
    byte[] result = new byte[8];
    for (int i = 7; i >= 0; i--) {
        result[i] = (byte)(l & 0xFF);
        l >>= 8;
    }
    return result;
}

public static long bytesToLong(final byte[] b) {
    long result = 0;
    for (int i = 0; i < 8; i++) {
        result <<= 8;
        result |= (b[i] & 0xFF);
    }
    return result;
}
公共静态字节[]长字节(长l){
字节[]结果=新字节[8];
对于(int i=7;i>=0;i--){
结果[i]=(字节)(l&0xFF);
l>>=8;
}
返回结果;
}
公共静态长bytestolog(最终字节[]b){
长结果=0;
对于(int i=0;i<8;i++){
结果>=字节大小;
}
返回结果;
}
公共静态长bytestolog(最终字节[]b){
长结果=0;
for(int i=0;i结果我将添加另一个可能最快的答案ׂ(是的,甚至比公认的答案还要快),但它不适用于每一个案例。但是,它适用于每一个可能的场景:

您可以简单地使用字符串作为中介。注意,这将为您提供正确的结果,即使使用字符串可能会产生错误的结果,只要您知道您使用的是“正常”这是一种提高效率并使代码更简单的方法,反过来必须对其操作的数据字符串使用一些假设

使用此方法的缺点:如果您正在使用一些ASCII字符,如ASCII表开头的这些符号,以下几行可能会失败,但让我们面对现实——您可能永远不会使用它们

Pro使用此方法:请记住,大多数人通常使用一些普通字符串,而不使用任何异常字符,因此该方法是最简单、最快的方法

从长到字节[]:

byte[] arr = String.valueOf(longVar).getBytes();
从字节[]到长:

long longVar = Long.valueOf(new String(byteArr)).longValue();

下面是使用Java 8或更新版本将
字节[]
转换为
的另一种方法:

private static int bytestpoint(最终字节[]字节,最终整数偏移量){

对于Long和ByteArray类型,断言offset+Integer.BYTESKotlin扩展:

fun Long.toByteArray() = numberToByteArray(Long.SIZE_BYTES) { putLong(this@toByteArray) }

private inline fun numberToByteArray(size: Int, bufferFun: ByteBuffer.() -> ByteBuffer): ByteArray =
    ByteBuffer.allocate(size).bufferFun().array()

@Throws(NumberFormatException::class)
fun ByteArray.toLong(): Long = toNumeric(Long.SIZE_BYTES) { long }

@Throws(NumberFormatException::class)
private inline fun <reified T: Number> ByteArray.toNumeric(size: Int, bufferFun: ByteBuffer.() -> T): T {
    if (this.size != size) throw NumberFormatException("${T::class.java.simpleName} value must contains $size bytes")

    return ByteBuffer.wrap(this).bufferFun()
}
fun Long.toByteArray()=numberToByteArray(Long.SIZE\u字节){putLong(this@toByteArray) }
私有内联乐趣编号ByteArray(大小:Int,bufferFun:ByteBuffer.(->ByteBuffer):ByteArray=
ByteBuffer.allocate(size).bufferFun().array()的值
@抛出(NumberFormatException::类)
fun ByteArray.toLong():Long=toNumeric(Long.SIZE_字节){Long}
@抛出(NumberFormatException::类)
私有内联乐趣ByteArray.toNumeric(大小:Int,缓冲乐趣:ByteBuffer.(->T):T{
if(this.size!=size)抛出NumberFormatException(${T::class.java.simpleName}值必须包含$size字节)
return ByteBuffer.wrap(this.bufferFun())
}

您可以在我的库中看到完整的代码

我发现这个方法非常友好

var b = BigInteger.valueOf(x).toByteArray();

var l = new BigInteger(b);

聪明…但每次转换都会创建并丢弃一个临时ByteBuffer。如果每条消息和/或很多消息都发送多个long,这就不好了。@Stephen-我只是做了足够的工作来演示如何使用ByteBuffer,但我继续添加了一个在实用程序类中使用它的示例。我认为ByTestOlog()此处将失败,因为put后的位置位于缓冲区的末尾,而不是开始处。我认为会出现缓冲区下溢异常。在Java 8之前,您可以使用Long.SIZE/Byte.SIZE而不是Long.BYTES来避免一个神奇的数字。bytebuffer的重用是非常有问题的,不仅仅是因为其他人评论的线程安全原因。N在这两者之间只需要一个“.clear()”
long longVar = Long.valueOf(new String(byteArr)).longValue();
fun Long.toByteArray() = numberToByteArray(Long.SIZE_BYTES) { putLong(this@toByteArray) }

private inline fun numberToByteArray(size: Int, bufferFun: ByteBuffer.() -> ByteBuffer): ByteArray =
    ByteBuffer.allocate(size).bufferFun().array()

@Throws(NumberFormatException::class)
fun ByteArray.toLong(): Long = toNumeric(Long.SIZE_BYTES) { long }

@Throws(NumberFormatException::class)
private inline fun <reified T: Number> ByteArray.toNumeric(size: Int, bufferFun: ByteBuffer.() -> T): T {
    if (this.size != size) throw NumberFormatException("${T::class.java.simpleName} value must contains $size bytes")

    return ByteBuffer.wrap(this).bufferFun()
}
var b = BigInteger.valueOf(x).toByteArray();

var l = new BigInteger(b);