2009-09-08 79 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