[英]Java: Efficiently converting an array of longs to an array of bytes
我有多個要寫入磁盤的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();
...但是我似乎找不到找到相反方向的功能。
我了解從long
到byte
轉換時有字節順序的注意事項,但我相信我已經解決了這些問題:我正在使用上面顯示的Buffer框架,無論本機字節順序如何,該框架默認為big endian。
不,沒有簡單的方法可以將long[]
轉換為byte[]
。
最好的選擇可能是用BufferedOutputStream
包裹FileOutputStream
,然后寫出每個long
的單個byte
值(使用按位運算符)。
另一個選擇是創建一個ByteBuffer
並將您的long
值放入ByteBuffer
,然后將其寫入FileChannel
。 這可以為您處理字節順序轉換,但會使緩沖更加復雜。
關於效率,事實上,許多細節幾乎沒有什么不同。 硬盤是迄今為止涉及到的最慢的部分,而且在將單個字節寫入磁盤所需的時間中,您可能已經將數千乃至數百萬個字節轉換為long。 每一個性能測試在這里也不會告訴你的執行表現什么,但對硬盤的性能。 毫無疑問,應該制定專門的基准,分別比較不同的轉換策略和不同的書寫方式。
假設主要目標是一種允許方便轉換且不會造成不必要開銷的功能,我想提出以下方法:
可以創建一個足夠大的ByteBuffer
,將其視為LongBuffer
,使用bulk 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
的內存開銷會非常大)
在這里操作。
我想到一個辦法: ByteBuffer.asLongBuffer()
返回的實例ByteBufferAsLongBufferB
,它包裝的ByteBuffer在一個接口作為處理數據的類long
s,而正確管理字節順序。 我可以擴展ByteBufferAsLongBufferB
,並添加一個方法來返回原始字節緩沖區( protected
)。
但這似乎深奧而令人費解,我覺得必須有一種更簡單的方法。 要么是這樣,要么是我的方法存在缺陷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.