Yol*_*ore 5 java binary performance parsing
我经常在Java EE应用程序套件中处理不同的二进制文件格式,即读入一些类结构并将其写回.我需要进行以下操作:
读取标志中的单个位,即
| uint16_t | 4 bits | 4 bits | uint16_t |
Run Code Online (Sandbox Code Playgroud)
应该变得像
a = stream.readUint16();
byte tmp = stream.readUint8();
b = (tmp & 0xf0) >> 4;
c = (tmp & 0xf)
d = stream.readUint16();
Run Code Online (Sandbox Code Playgroud)读取不同编码的字符串,有时是带有\0结尾的动态长度字符串
typedef struct在C中声明a慢一个数量级,将其作为块读取并在内存中进行类型转换到目前为止,我已经分析了我的选项,发现有:
RandomAccessFile - 标准Java中最好的一个,具有正确的搜索和定位方法,字符串读取等,但由于缺乏缓冲操作,有时难以忍受地缓慢; 也没有对流的位级访问,也没有不同的字节顺序支持FileInputStream - 只能读取单个字节,必须手工重建原始数据类型; 没有寻求*Reader 相互作用 - 基本上,只能读取字节和字节数组,可以跳过,标记和重置,但如果多次搜索,它们往往会泄漏内存 reset(); skip(seekAmount);我搜索过谷歌,我搜索过StackOverflow.这个问题 - 如何解析/编码二进制消息格式? - 解决相同的问题,但有一些我没有的奇怪的非对齐位要求.
所以,问题是 - 我是否忽略了某些问题,并且有更好的解决方案可以解决我提到的所有问题?
ByteBuffer拥有您需要的一切.
它也可能是纯Java中最快的选择(不包括JNI,sun.misc.Unsafe等)
get,getShort,getInt等等读取所有原语类型和字节数组;order 在BIG_ENDIAN和LITTLE_ENDIAN之间切换;position 寻求;CharsetEncoder,CharsetDecoder可以直接在ByteBuffer中编码/解码字符串;FileChannel.map 创建映射到文件的ByteBuffer;我讨厌建议将此作为解决方案,但考虑到您似乎对如何在 C 中执行此操作有一些了解,您可以在 C 中构造一个适当函数的库,然后用 JNI 包装它并在您的应用程序中使用它。
也许这只是“本地化”适合您的用例的罕见情况之一?