How to read erlang term from redis by using java c

2019-06-02 21:48发布

问题:

e.g. I save the tuple T = {k1, v1, k2, v2} to the redis by jedis:

 eredis:q(Conn, ["SET", <<"mykey">>, term_to_binary(T)]).

I am trying to use the code below to read this erlang term:

Jedis j =  Redis.pool.getResource();
byte[] t = j.get("mykey").getBytes();
OtpInputStream ois = new OtpInputStream(t);
System.out.println(OtpErlangObject.decode(ois));

The error is: com.ericsson.otp.erlang.OtpErlangDecodeException: Uknown data type: 239.

So how can I get the erlang term correctly?


Erlang side:

term_to_binary({k1, v1, k2, v2}).

<<131,104,4,100,0,2,107,49,100,0,2,118,49,100,0,2,107,50, 100,0,2,118,50>>

Java side:

j.get("mykey").getBytes():

-17 -65 -67 104 4 100 0 2 107 49 100 0 2 118 49 100 0 2 107 50 100 0 2 118 50.

It seems that only the first 3 byte are different. So I change them to byte(131), and then it can be printed correctly with System.out.println(OtpErlangObject.decode(ois)).

But when the term is more complicated, such as for a record with list inside, it wont work. cuz some other characters will appear not only at the head of the data but also the end and the middle.

Why the data I saved is different from what I got?

回答1:

The negative numbers at the beginning of the byte array are not valid values for erlang external term syntax.

I would assume that since you have been storing the erlang terms in redis this way for some time, you are inserting them correctly.

That really only leaves one thing: When you call getBytes() your encoding is off, it is most likely using whatever encoding is set as the default on your system (probably UTF-8, but I'm not sure). Really what you want to do is pass a different encoding to getBytes(), probably like this: getBytes("US-ASCII").

check out the documentation for encodings are available.

Heres a link on SO that shows how to convert a string to an ASCII byte array.