マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

MessagePack for Javaを使ってみる その2

前回は古いバージョンを使っていたらしく、何か聞いていた使い方と違っていた。とりあえず、最新版(http://github.com/msgpack)を入手してきて、新しい方法を試す。とはいってもシリアライズはそのまんまで、デシリアライズ時の返り値とその使い方に差がちょっとある。

前のバージョンではUnpackerを拡張for文に渡すとObjectが返ってきたが、今回はMessagePackObjectが返ってくる。実際は、MessagePackObjectはabstractなので、それを継承したクラスのオブジェクトが返ってくる。このクラスにはas〜というメソッドがあり、これを呼び出すと値が返ってくる。例えば整数をシリアライズして、デシリアライズして得たMessagePackObjectのasIntを呼び出すと整数が返ってくる。ここでasStringを呼び出すと例外が返ってくる。とりあえずソースコード

import org.msgpack.Packer;
import org.msgpack.Unpacker;
import org.msgpack.MessagePackObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class Test{
    public static void main(String[] args) throws Exception{
        //まずシリアライズ

        // 出力先のOutputStream
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // シリアライザを初期化
        Packer pack = new Packer(out);

        // シリアライズ
        pack.pack(1);
        pack.pack(100);
        pack.pack(10000);
        pack.pack(100000);
        out.close();

        byte[] buff = out.toByteArray();

        //ここからデシリアライズ

        // 入力元のInputStream
        ByteArrayInputStream in = new ByteArrayInputStream(buff);
        // デシリアライザを初期化(ストリームシリアライザ)
        Unpacker unpack = new Unpacker(in);

        //拡張for文で取り出す
        for(MessagePackObject obj : unpack){
            System.out.println(obj.asInt());
        }
    }
}

拡張for文の部分を

for(MessagePackObject obj : unpack){
    System.out.println(obj.asString());
}

とすると例外が発生する。以下文字列のシリアライズ、デシリアライズ

import org.msgpack.Packer;
import org.msgpack.Unpacker;
import org.msgpack.MessagePackObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class Test{
    public static void main(String[] args) throws Exception{
        //まずシリアライズ

        // 出力先のOutputStream
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // シリアライザを初期化
        Packer pack = new Packer(out);

        // シリアライズ
        pack.pack("Hello World");
        pack.pack("Test");
        pack.pack("Success!");
        out.close();

        byte[] buff = out.toByteArray();

        //ここからデシリアライズ

        // 入力元のInputStream
        ByteArrayInputStream in = new ByteArrayInputStream(buff);
        // デシリアライザを初期化(ストリームシリアライザ)
        Unpacker unpack = new Unpacker(in);

        //拡張for文で取り出す。
        for(MessagePackObject obj : unpack){
            System.out.println(obj.asString());
        }
    }
}

以下、別々の型を入れてもOKという例

import org.msgpack.Packer;
import org.msgpack.Unpacker;
import org.msgpack.MessagePackObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Iterator;

public class Test{
    public static void main(String[] args) throws Exception{
        //まずシリアライズ

        // 出力先のOutputStream
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // シリアライザを初期化
        Packer pack = new Packer(out);

        // シリアライズ
        pack.pack("Hello World");
        pack.pack(Short.MAX_VALUE);
        pack.pack(Integer.MAX_VALUE);
        pack.pack("Success!");
        out.close();

        byte[] buff = out.toByteArray();

        //ここからデシリアライズ

        // 入力元のInputStream
        ByteArrayInputStream in = new ByteArrayInputStream(buff);
        // デシリアライザを初期化(ストリームシリアライザ)
        Unpacker unpack = new Unpacker(in);

        Iterator<MessagePackObject> iterator = unpack.iterator();

        System.out.println(iterator.next().asString());
        System.out.println(iterator.next().asShort());
        System.out.println(iterator.next().asInt());
        System.out.println(iterator.next().asString());
    }
}

結果


Hello World
32767
2147483647
Success!