在我们的Java应用程序套件中,我经常处理不同的二进制文件格式,即读入某些类结构并将它们写回。我需要做这样的手术:
\0
结尾的动态长度字符串typedef struct
、将它作为块读取并在内存中进行类型转换慢一个数量级。到目前为止,我已经分析了我的选择,发现有:
RandomAccessFile
-标准Java中最好的一种,有正确的查找和定位方法、字符串读取等,但有时由于操作中缺乏缓冲而慢得令人难以忍受;也没有对流的位级访问,也没有不同的endianness支持。FileInputStream
-只能读取单个字节,必须手工重建原始数据类型;不需要查找。*Reader
接口-基本上只能读取字节和字节数组,可以跳过、标记和重置,但是如果以reset(); skip(seekAmount);
的形式多次执行查找,它们往往会泄漏内存。我搜索过谷歌,我搜索过StackOverflow。这个问题-- How to parse/encode binary message formats? --解决了同样的问题,但是有着我没有的奇怪的非对齐位要求。
所以,问题是-我是不是忽略了什么,对于这个问题有什么更好的解决方案来解决我提到的所有问题吗?
发布于 2016-03-12 13:25:55
ByteBuffer有你需要的一切。
它也可能是纯Java中最快的选项(不包括JNI、sun.misc.Unsafe等)。
get
、getShort
、getInt
等读取所有基本类型和字节数组;order
在BIG_ENDIAN和LITTLE_ENDIAN之间切换;position
用于寻找;CharsetEncoder
,CharsetDecoder
可以直接在ByteBuffer中对字符串进行编/解码;FileChannel.map
创建映射到文件的ByteBuffer;发布于 2016-03-12 11:55:20
我不想将此作为解决方案,但考虑到您似乎对如何在C中实现此操作有一定的了解,您可以在C中构造一个适当函数库,然后用JNI包装并在应用程序中使用它。
也许这只是“土生土长”适合于您的用例的少数情况之一?
https://stackoverflow.com/questions/35957170
复制相似问题