javolution-core-java-6.1.0.jar 的使用

官方网址:http://javolution.org/apidocs/javolution/io/Struct.html

第一步:导包

第二步:创建继承的结构体

结构体定义如下所示:

public class SKJ_RECORD_INFO extends Struct {

    Unsigned8 infoID = new Unsigned8();             // 本数据结构标识,应为0x02
    Unsigned8 infoVersion = new Unsigned8();        // 本书数据结构格式版本,应为0x00
    Unsigned8 RecordLen = new Unsigned8();          // 交易记录的大小(字节数)。目前为80
    Unsigned8 RecordVersion = new Unsigned8();      // 交易记录格式版本号,目前为0x30
    Unsigned32 RecordMenSize = new Unsigned32();    // 交易记录存储空间总大小,单位:字节
    Unsigned16 RecordCntMax = new Unsigned16();     // 交易记录存储从简最大的记录数量
    Unsigned16 RecordCntTotal = new Unsigned16();   // 当前交易记录总数量,包括已采集的记录和未采集的记录
    Unsigned16 RecordCntCollected = new Unsigned16(); // 当前已采集的记录数量
    Unsigned16 RecordCntUnCollected = new Unsigned16(); // 当前尚未采集的记录数量
    Unsigned16 RecotdCntFree = new Unsigned16();    // 当前空闲的记录存储控件数量


    public void putData(byte[] data) {
        int structLen = this.size();

        byte[] temp = new byte[structLen];
        if (data.length >= structLen) {
            System.arraycopy(data, 0, temp, 0, structLen);
        } else {
            // 少于当前的结构的大小,以“0”来补充
            System.arraycopy(data, 0, temp, 0, data.length);
        }
        ByteBuffer buff = ByteBuffer.wrap(temp);
        buff.order(this.byteOrder());
        this.setByteBuffer(buff, 0);
    }


    // 一定要加上这个,不然会出现对齐的问题
    @Override
    public boolean isPacked() {
        return true;
    }

    // 设置为小端数据
    @Override
    public ByteOrder byteOrder() {
        return ByteOrder.LITTLE_ENDIAN;
    }

}

测试:

public class SKJ_RECORD_INFOTest {
    @Before
    public void setUp() throws Exception {
        byte[] data = new byte[18];
        for (int i = 0; i < data.length; i++) {
            data[i] = (byte) i;
        }

        SKJ_RECORD_INFO info = new SKJ_RECORD_INFO();
        ByteBuffer b = ByteBuffer.wrap(data);
        b.order(ByteOrder.LITTLE_ENDIAN);
        info.setByteBuffer(b, 0);
        System.out.println(info.size());
        System.out.println(info.infoID);
        System.out.println(info.RecotdCntFree);
        System.out.println("info.RecordMenSize:" + info.RecordMenSize);
        System.out.println(info.toString());
        System.out.println("-----");
        data[0] = 100;
        System.out.println(info.toString());
    }

    @Test
    public void putData() throws Exception {
    }

}

结果:

18
0
4368
info.RecordMenSize:117835012
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11
-----
64 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11

说明了一个问题:当前的info和字节数据data是关联在一起的了。data的数据改变,其对应indo的属性也会跟着改变。

public class SKJ_RECORD_INFOTest {
    @Before
    public void setUp() throws Exception {
        byte[] data = new byte[17];
        for (int i = 0; i < data.length; i++) {
            data[i] = (byte) i;
        }

        SKJ_RECORD_INFO info = new SKJ_RECORD_INFO();
        ByteBuffer b = ByteBuffer.wrap(data);
        b.order(ByteOrder.LITTLE_ENDIAN);
        info.setByteBuffer(b, 0);
        System.out.println(info.size());
        System.out.println(info.infoID);
        System.out.println(info.RecotdCntFree);  -- 报错了
        System.out.println("info.RecordMenSize:" + info.RecordMenSize);
        System.out.println(info.toString());
        System.out.println("-----");
        data[0] = 100;
        System.out.println(info.toString());
    }

    @Test
    public void putData() throws Exception {
    }

}

结果:

18
0

java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkIndex(Buffer.java:546)
at java.nio.HeapByteBuffer.getShort(HeapByteBuffer.java:314)
at javolution.io.Struct$Unsigned16.get(Struct.java:1294)
at javolution.io.Struct$Unsigned16.toString(Struct.java:1309)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.lanhetech.core.collectInfo.SKJ_RECORD_INFOTest.setUp(SKJ_RECORD_INFOTest.java:23)
……

说明了另一个问题:当前的data数据小于结构体info的大小时,info.setByteBuffer(b, 0);不会出错,但是引用到没有不够长度的数据时,就会出错了。

为了解决以上2个问题,新增一个putData()方法

public void putData(byte[] data) {
        int structLen = this.size();

        byte[] temp = new byte[structLen];
        if (data.length >= structLen) {
            System.arraycopy(data, 0, temp, 0, structLen);
        } else {
            // 少于当前的结构的大小,以“0”来补充
            System.arraycopy(data, 0, temp, 0, data.length);
        }
        ByteBuffer buff = ByteBuffer.wrap(temp);
        buff.order(this.byteOrder());
        this.setByteBuffer(buff, 0);
    }
原文地址:https://www.cnblogs.com/H-BolinBlog/p/6866092.html