如何将Java Long转换为byte[]以便于Cassandra使用?

4

懒惰的程序员警告. :)

Cassandra将列值存储为字节(Java示例)。指定LongType比较器将这些字节作为长整型进行比较。我想要一个长整型值转换为适用于Cassandra的byte[]。如何做到?我查找了一段时间。我认为你们可以更快地帮助我。

编辑:

Alexander和Eli的答案都同意此反向转换。谢谢!


好的,你只是挑剔而已。没关系,甚至令人钦佩 :) - President James K. Polk
4个回答

5
我会将长整型写入一个ByteArrayOutputStream中,该流被包装在DataOutputStream中,然后检索原始字节。但是这样做总是以大端字节顺序(最高有效字节在前)给出数据。
public static byte[] getBytes(Long val)
    throws IOException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    dos.writeLong(val);
    return baos.toByteArray();
}

如果您想指定字节顺序,可以使用ByteBuffer类:

public static byte[] getBytes(Long val)
{
    ByteBuffer buf = ByteBuffer.allocate(8);
    buf.order(ByteOrder.BIG_ENDIAN);
    buf.putLong(val);
    return buf.array();
}

你知道分配 ByteBuffer 和直接分配 byte[] 的比较吗?我倾向于使用仅 byte[] 的解决方案,因为它似乎更便宜。 - dfrankow
我想我需要找到Cassandra的字节序。 - dfrankow
@dfrankow:ByteBuffer 是用 C++ 编写的,因此可能是为了效率而设计的。然而,我的建议是,在你分析代码并确定哪些地方存在低效之前,不要担心这些微观优化。程序员对于自己代码中的慢速区域猜测得出奇迹的糟糕 :) - Eli Courtwright

3

以下是从Java 6中复制粘贴的内容:DataOutputStream.writeLong

public final void writeLong(long v) throws IOException {
    writeBuffer[0] = (byte)(v >>> 56);
    writeBuffer[1] = (byte)(v >>> 48);
    writeBuffer[2] = (byte)(v >>> 40);
    writeBuffer[3] = (byte)(v >>> 32);
    writeBuffer[4] = (byte)(v >>> 24);
    writeBuffer[5] = (byte)(v >>> 16);
    writeBuffer[6] = (byte)(v >>>  8);
    writeBuffer[7] = (byte)(v >>>  0);
    out.write(writeBuffer, 0, 8);
incCount(8);
}

以下是针对您的情况的修改建议。
public final byte[] longToBytes(long v) {
    byte[] writeBuffer = new byte[ 8 ];

    writeBuffer[0] = (byte)(v >>> 56);
    writeBuffer[1] = (byte)(v >>> 48);
    writeBuffer[2] = (byte)(v >>> 40);
    writeBuffer[3] = (byte)(v >>> 32);
    writeBuffer[4] = (byte)(v >>> 24);
    writeBuffer[5] = (byte)(v >>> 16);
    writeBuffer[6] = (byte)(v >>>  8);
    writeBuffer[7] = (byte)(v >>>  0);

    return writeBuffer;
}

1
你是因为效率更高才展开循环吗?HotSpot编译器会自动帮你做这件事吗? - dfrankow
抱歉,我想你并没有做出那个选择,你只是跟随writeLong()的操作。 - dfrankow

2
您可以使用移位和掩码来拆分字节,或者更容易的方法是使用ByteBuffer.wrap将一个8个字节长的字节数组进行包装,并使用putLong方法。您必须首先使用ByteBuffer.order方法设置ByteOrder。

2

您可以使用Cassandra的实用程序类:ByteBufferUtil.bytes(long n)

注:原文已经是中英混合,因此直接翻译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接