2009-09-08 80 views
3

我通过Python与Java应用程序接口。我需要能够构造包含utf-8字符串的字节序列。 Java使用在DataInputStream.readUTF()修订的UTF-8编码,这是不Python支持(yet at leastPython中修改的UTF-8字符串

任何人都可以点我在正确的方向来构建的Java修订的UTF-8字符串在Python?

更新#1:若要查看有关java修改的utf-8的更多信息,请查看第550行上的DataInput接口的readUTF方法herehere in the Java SE docs

更新#2:我试图通过调用DataInputStream.readUTF使用此修改的utf8格式通过POST请求读取字符串的第三方JBoss Web应用程序接口(抱歉,有关正常java utf8字符串操作的任何混淆)。

在此先感谢。

+1

“修改UTF-8”是什么意思?据我所知,Java使用完全标准的UTF-8,如果你要求它编码为UTF-8。请注意,虽然Java的本地字符串格式是UTF-16。 – 2009-09-08 09:41:29

+0

嗨,Jon,我在DataInput接口中添加了一个readUTF方法的链接,它提到了一点。我会尝试挖掘更多信息。 – QAZ 2009-09-08 09:46:00

+2

维基百科上有一些信息:http://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8(所以,序列化,一些JNI和类内字符串常量)。 – McDowell 2009-09-08 09:47:48

回答

1

好吧,如果您需要阅读DataInput.readUTF的格式,我想您只需将(记录完备的)格式转换为Python即可。

它看起来并不像特别难做。在读取长度和二进制数据本身之后,我建议您使用第一遍来计算输出中将有多少个Unicode字符,然后在第二遍中相应地构造一个字符串。在不了解Python的情况下,我不知道如何有效地构建字符串的细节,但是鉴于链接规范,我无法想象它会非常困难。您可能希望查看现有UTF-8解码器的源代码作为起点。

4

可以忽略修订的UTF-8编码(MUTF-8)和刚将其视为UTF-8。在Python方面,您可以像这样处理它,

  1. 将字符串转换为普通的UTF-8并将字节存储在缓冲区中。
  2. 以big-endian的二进制形式写入2字节的缓冲区长度(不是字符串长度)。
  3. 写下整个缓冲区。

我已经在PHP中完成了这个工作,Java根本没有抱怨我的编码(至少在Java 5中)。

MUTF-8主要用于JNI和其他带有以空字符结尾的字符串的系统。与普通UTF-8唯一的区别是U + 0000是如何编码的。正常的UTF-8使用1字节编码(0x00),MUTF-8使用2字节(0xC0 0x80)。首先,在任何Unicode文本中都不应该有U + 0000(无效的代码点)。其次,DataInputStream.readUTF()不强制执行编码,因此它很乐意接受任何一种。

编辑:Python代码应该是这样的,

def writeUTF(data, str): 
    utf8 = str.encode('utf-8') 
    length = len(utf8) 
    data.append(struct.pack('!H', length)) 
    format = '!' + str(length) + 's' 
    data.append(struct.pack(format, utf8)) 
+0

听起来不错,thansk。现在检查它 – QAZ 2009-09-08 11:59:53

+0

我正在学习Python,所以我转换了我的PHP函数。 – 2009-09-08 12:18:35

+3

U + 0000不是唯一的区别。对于将用UTF-16中的代理对表示的代码点,经过修改的UTF-8将对中的每个组件编码为独立的UTF-8代码点。这非常可怕,因为这意味着您必须从“已修改的UTF-8”转换为UTF-16,然后返回以便对正确的代码点进行编码。 – Cogwheel 2013-01-30 19:55:59

0

我知道这个问题是非常非常老了,但我还是想贡献,因为我在同样的问题了,解决它

我在openjdk源代码中找到了这个修改后的utf8的实现,并将它转换为python。这里是我创建的要点link