将 long 转换为字节数组并将其添加到另一个数组
Posted
技术标签:
【中文标题】将 long 转换为字节数组并将其添加到另一个数组【英文标题】:Convert long to byte array and add it to another array 【发布时间】:2011-05-16 23:51:14 【问题描述】:我想更改字节数组中的值以将长时间戳值放入 MSB。有人可以告诉我最好的方法是什么。我不想逐位插入值,我认为这是非常低效的。
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 long 转换为字节数组)
创建一个 Spark udf 函数以迭代字节数组并将其转换为数字