将 long 转换为字节数组并将其添加到另一个数组

Posted

技术标签:

【中文标题】将 long 转换为字节数组并将其添加到另一个数组【英文标题】:Convert long to byte array and add it to another array 【发布时间】:2011-05-16 23:51:14 【问题描述】:

我想更改字节数组中的值以将长时间戳值放入 M​​SB。有人可以告诉我最好的方法是什么。我不想逐位插入值,我认为这是非常低效的。

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

我想要的是这样的:

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

这样的事情可能吗。在此字节数组中编辑/插入值的最佳方法是什么。因为 byte 是一个原语,我不认为有一些我可以使用的直接实现?

编辑: 貌似System.currentTimeMillis()Calendar.getTimeInMillis()快,所以把上面的代码换成它,有错请指正。

【问题讨论】:

这很有帮助:***.com/questions/5399798/… 我认为您的索引计数有误,请查看此问题:***.com/questions/5399798/… 【参考方案1】:

对我来说 ByteBuffer 和其他实用程序从时间角度来看是昂贵的。您可以使用以下 2 种方法:

//第一种方法(即使用第二种方法),它返回分配并实现的数组

public byte[] longToByteArray(long value) 

        byte[] array = new byte[8];

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

// 如果您已经分配了缓冲区,并且您想将 long 写入数组中的特定位置,则此方法很有用。

public void longToByteArray(long value, byte[] array, int startFrom) 

    for (int i=7; i>=0; i--)
    
        array[startFrom+7-i] = (byte) (value >> i*8);
    

【讨论】:

【参考方案2】:

有多种方法可以做到:

使用ByteBuffer(最佳选择 - 简洁易读):

byte[] bytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(someLong).array();

您也可以使用DataOutputStream(更详细):

ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(someLong);
dos.close();
byte[] longBytes = baos.toByteArray();

最后,您可以手动执行此操作(取自 Hector 代码中的 LongSerializer)(更难阅读):

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

然后你可以通过一个简单的循环将这些字节附加到你现有的数组中:

// 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];

【讨论】:

我发现我必须像这样在 ByteByffer 上设置顺序,否则字节的顺序与我期望的相反 byte[] bytes = ByteBuffer.allocate(8).order (ByteOrder.LITTLE_ENDIAN).putLong(bits).array(); 我假设 Java 是 generally big endian,而 x86 是小端。 为了避免对 long 的大小进行硬编码,我会使用 allocate(Long.SIZE) @mikejones 请注意,Long.SIZE 将为您提供用于表示 Long (docs.oracle.com/javase/6/docs/api/java/lang/Long.html#SIZE) 的位数。您需要 (Long.SIZE / Byte.SIZE) 来匹配上面的示例。 @overthink Java 8 为此引入了一个 BYTES 常量 (docs.oracle.com/javase/8/docs/api/java/lang/Long.html#BYTES)。【参考方案3】:

如果你想真正深入了解......

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
    ;

【讨论】:

【参考方案4】:

我正在更新这篇文章,因为我刚刚宣布了一个库的预发布版本,它将把 long 转换为字节数组(然后再转换回来)。该库非常小,可以将任何 java 原语转换为字节数组。

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

如果你使用它,你可以做一些事情,比如将长数组转换为字节数组:

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);

您也可以转换单个 long 值。

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

随时提供一些反馈。

2013 年 10 月 4 日更新: 我现在已经发布了库的制作http://rschilling.wordpress.com/2013/10/04/pend-oreille-official-1-0-release/

【讨论】:

【参考方案5】:

看起来您不能对字节数组进行切片以将某些内容插入到子集中,而无需逐字节进行。看Grab a segment of an array in Java without creating a new array on heap。基本上我要做的是设置创建一个 64 字节数组并为其设置时间,然后将一个空白的 64 字节数组附加到它。或者只是一个字节一个字节地做。

【讨论】:

以上是关于将 long 转换为字节数组并将其添加到另一个数组的主要内容,如果未能解决你的问题,请参考以下文章

将一个原始long数组转换为Longs列表

变量周围的堆栈已损坏(将 long long 转换为字节数组)

如何在C ++中将字节数组中的整数转换为数字

创建一个 Spark udf 函数以迭代字节数组并将其转换为数字

将 4 个字节转换为无符号 32 位整数并将其存储在 long

将 byte[] 转换为原始二维数组