将Erlang的UTF-8编码字符串转换为java.lang.String

4
Java节点接收一个用UTF-8编码的Erlang字符串,其类类型为OtpErlangString。如果我仅使用.toString()或.stringValue(),则生成的java.lang.String具有无效的代码点(基本上将Erlang字符串中的每个字节视为不同的字符)。
现在,我想在创建Java字符串时使用new String(bytes, "UTF-8"),但如何从OtpErlangString获取字节?

Java.io.StringReader有帮助吗? - Reddy
我不明白怎么用。你能建议一个使用方式吗? - Martin Dimitrov
我的错误,我以为OtpErlangString扩展了String。 - Reddy
我不知道这是否有帮助,但是有一个encode()方法,它可以写入到扩展了ByteArrayOutputStream的OtpOutputstream中。这个ByteArrayOutputStream有toString方法,你可能可以使用这个方法。 - Reddy
encode() 用于将字符串转换为等效的 Erlang 外部表示形式。我认为我不应该将其用于此目的。 - Martin Dimitrov
1个回答

1

当你在Java端使用UTF8字符时,得到OtpErlangString是很奇怪的。如果我只使用ASCII字符,我会得到这种类型的对象。如果我至少添加一个UTF8字符,结果类型将变为OtpErlangList(这是合乎逻辑的,因为在Erlang中字符串只是整数列表),然后我可以使用它的stringValue()方法。所以,在从Erlang发送字符串形式之后:

(waco@host)8> {proc, java1@host} ! "ąćśźżęółńa".
[261,263,347,378,380,281,243,322,324,97]

在Java节点上,我使用以下代码接收并打印它:

OtpErlangList l = (OtpErlangList) mbox.receive();
System.out.println(l.stringValue());

输出结果正确:

ąćśźżęółńa

然而,如果在您的情况下不是这种情况,您可以尝试通过强制使用OtpErlangList表示来解决它,例如通过将空元组作为字符串列表的第一个元素添加:

(waco@wborowiec)11> {proc, java1@wborowiec} ! [{}] ++ "ąćśźżęółńa".
[{},261,263,347,378,380,281,243,322,324,97]

在Java端可能是这样的:

OtpErlangList l = (OtpErlangList) mbox.receive();
// get rid of an extra tuple
OtpErlangObject[] strArr = Arrays.copyOfRange(l.elements(), 1, l.elements().length);
OtpErlangList l2 = new OtpErlangList(strArr);
System.out.println(l2.stringValue());

发送包含"да"(俄语中的"是")的列表[208, 180, 208, 176]将导致生成OtpErlangString对象。在列表前面添加一个空元组以强制创建OtpErlangList对象非常好,但是难道没有更简单的解决方案吗?是否有一种方法可以从OtpErlangString对象中提取二进制数组? - Martin Dimitrov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接