我正在尝试编写一个灵活的class,它将允许我使用Java中定义的class解析二进制数据结构。
当我纯粹使用int
变量时,我能够实现我想要的,但一旦我继续使用类似byte[]
的类型,我就会绊倒。请参阅以下示例。
public class ReflectionTest {
public ReflectionTest(MappedByteBuffer buffer, int start) {
buffer.position(start);
Field[] fields = this.getClass().getDeclaredFields();
try {
for (Field field : fields) {
if (field.getType().toString().equals("int")) {
//Set the value of the int field
field.setInt(this, buffer.getInt());
} else if (field.getType().toString().equals("class [B")) {
//Set the value of the byte array...
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class ReflectionTest1 extends ReflectionTest {
public byte[] Signature = new byte[4];
public byte[] Version = new byte[4];
public int Time;
public ReflectionTest1(MappedByteBuffer buffer, int start) {
super(buffer,start);
}
}
public Main() {
try {
FileChannel channel = new RandomAccessFile("test.bin", "r").getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
buffer.order(ByteOrder.LITTLE_ENDIAN);
ReflectionTest1 test = new ReflectionTest1(buffer,0);
} catch (Exception e) {
e.printStackTrace();
}
}
我很困惑如何获得ReflectionTest1
中定义的数组的长度(例如,Signature
的长度为4),从而将所提供的MappedByteBuffer
中的正确数据量读入字段。
这在Java中可能吗?我的理由是,我有很多结构,其中一些结构有大量的元素。我可以使用Reflection根据子类字段的类型和长度自动填充子类字段,而不是重复自己(对每个字段执行getInt/get)。
有很多库提供类似的功能,但没有一个库提供我所需要的灵活性(至少从我所能找到的来看)。
如有任何帮助或见解,我们将不胜感激!:)
要反射式访问数组,请使用java.lang.reflect.Array.
然后你的代码应该是:
if (int.class.equals(field.getType())
{
...
}
else if (field.getType().isArray() && byte.class.equals(field.getType().getComponentType()))
{
...
}
假设您不想将整个缓冲区读取到字节数组中,那么如何知道数组的大小将是您的序列化机制专有的(这可能会使switch语句无效-应该用从缓冲区读取的switch-On值替换它)。
一种常见的方法是先编写类型,然后控制如何解释接下来的内容。在数组的情况下,接下来是长度,然后是数组内容。
老实说,你最好使用第三方库,比如谷歌的协议缓冲区,它已经涵盖了这一点以及更多。
看看java.lang.reflect.Array,它拥有访问数组的长度和单个元素所需的所有方法。