Java:有效地将long数组转换为字节数组
我有longs
我要写入磁盘的longs
。 最有效的磁盘I / O函数采用字节数组,例如:
FileOutputStream.write(byte[] b, int offset, int length)
…所以我想首先将long[]
转换为byte[]
(每个long
8个字节)。 我很难找到一个干净的方法来做到这一点。
似乎不允许直接类型转换:
ConversionTest.java:6: inconvertible types found : long[] required: byte[] byte[] byteArray = (byte[]) longArray; ^
通过迭代数组很容易进行转换,例如:
ByteBuffer bytes = ByteBuffer.allocate(longArray.length * (Long.SIZE/8)); for( long l: longArray ) { bytes.putLong( l ); } byte[] byteArray = bytes.array();
…然而,这似乎远不如简单地将long []视为一系列字节。
有趣的是,在读取文件时,使用Buffers很容易从byte[]
“转换”为long:
LongBuffer longs = ByteBuffer.wrap(byteArray).asLongBuffer();
…但我似乎找不到任何相反方向的function。
我理解在从long
转换为byte
时会有endian注意事项,但我相信我已经解决了这些问题:我正在使用上面显示的Buffer框架,默认为big endian,无论本机字节顺序如何。
关于效率,事实上很多细节几乎没有什么区别。 到目前为止,硬盘是这里涉及的最慢的部分,并且在将单个字节写入磁盘所需的时间内,您可以将数千甚至数百万字节转换为long。 这里的每个性能测试都不会告诉您有关实现性能的任何信息,而是告诉您有关硬盘性能的信息。 有疑问的是,应该制作专门的基准,比较不同的转换策略,并分别比较不同的写作方法。
假设主要目标是允许方便转换并且不会产生不必要的开销的function,我想提出以下方法:
可以创建一个足够大小的ByteBuffer
,将其视为LongBuffer
,使用批量LongBuffer#put(long[])
方法(它负责必要的字节序转换,并尽可能高效),以及最后,使用FileChannel
将原始的ByteBuffer
(现在填充了long
值)写入文件。
按照这个想法,我认为这种方法很方便,而且(很可能)效率很高:
private static void bulkAndChannel(String fileName, long longArray[]) { ByteBuffer bytes = ByteBuffer.allocate(longArray.length * Long.BYTES); bytes.order(ByteOrder.nativeOrder()).asLongBuffer().put(longArray); try (FileOutputStream fos = new FileOutputStream(fileName)) { fos.getChannel().write(bytes); } catch (IOException e) { e.printStackTrace(); } }
(当然,有人可能会争论是否分配“大”缓冲区是最好的想法。但是由于Buffer
类的便捷方法,这可以很容易地并且通过合理的努力被修改为用适当的方法编写数据的“块”。大小,对于一个人真的想写一个巨大的数组而且创建相应的ByteBuffer
的内存开销会非常大)
不,没有一种简单的方法可以从long[]
转换为byte[]
。
您最好的选择可能是使用BufferedOutputStream
包装FileOutputStream
,然后为每个long
写出单独的byte
值(使用按位运算符)。
另一个选择是创建一个ByteBuffer
并将long
值放入ByteBuffer
,然后将其写入FileChannel
。 这会为您处理字节序转换,但会使缓冲更复杂。
OP在这里。
我想到了一种方法: ByteBuffer.asLongBuffer()
返回ByteBuffer.asLongBuffer()
一个实例,这是一个在接口中包装ByteBuffer的类,用于在正确管理字节序的同时处理数据。 我可以扩展ByteBufferAsLongBufferB
,并添加一个方法来返回原始字节缓冲区( protected
)。
但这似乎是如此深奥和令人费解,我觉得必须有一个更简单的方法。 无论是那种,还是我的方法中的某些东西都是有缺陷的。