2012-05-23 48 views
2

我正在嘗試編寫一個使用UTF-8編碼將Java對象序列化爲字符串的函數。這是我的實現:使用UTF-8將Java對象序列化爲字符串

public static String serializeToString(DefaultMutableTreeNode tree) { 
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    try { 
     ObjectOutput out = new ObjectOutputStream(byteArrayOutputStream); 
     out.writeObject(tree); 
     return byteArrayOutputStream.toString("UTF-8"); 
    } catch (IOException e) { 
     return null; 
    } 
} 

但是,它似乎沒有工作。我嘗試將結果字符串傳遞到只接受UTF-8編碼的數據庫,但因編碼問題導致錯誤。

我的問題是:

  1. 什麼是我實現的問題?
  2. 如何檢查結果字符串是否使用UTF-8?

非常感謝

問候

+3

你得到的具體錯誤是什麼? – Oleksi

回答

2

這不是一個好主意,任意的二進制數組並不總能轉化爲有效的UTF-8序列。您應該將數組作爲二進制blob存儲在數據庫中,或者將數組轉換爲類似於Base64編碼的字符串。

1

你一定會在你的字符串中得到不可打印的字符,而數據庫根本不會喜歡。 Java ByteArrayOutputStream文檔排序提示它可能將可打印字符重新編碼爲可打印字符,但在查看代碼時,我看不到它執行任何操作,只是停止程序並顯示錯誤。我也看不到你將來會用這樣一串字符串做什麼。

一個字節的256個可能值只有一部分(約四分之一)是有效的ASCII字符。大多數數據庫不會將它們作爲字符串的一部分。因此你的錯誤信息。 (Unicode和UTF-8也有同樣的問題。)

我曾經通過將每6位轉換爲包含可打印字符的字節將數據轉換爲可打印字符的方式將二進制數據存儲在數據庫中。但我使用簡單的ASCII編碼,並且我編寫了代碼將返回的字符轉換爲二進制。然後,我可以將二進制數據存儲在數據庫字符列中,並在稍後檢索。我被強迫進入了它;我不會推薦你這樣做。

如果你想看看你的「字符串」是什麼樣的,只需將每個字節打印出一個整數並與ASCII表進行比較。你可能會看到這個問題,而不需要考慮Unicode的優點。

+0

@StephenC:我已經看了很長一段時間,但大多數ASCII用戶每字節需要一個字符,第一個字節總是爲零,所以你必須給它們8位字符。然後,可用的128個值中有相當一部分不是可打印的字符,並且根據我的經驗,數據庫不會讓它們出現在字符列中。因此,六位數據(64個值)適合一個字節作爲可打印字符,但是,無可否認,還剩餘一些空間(爲了使編程更容易而犧牲了)。 – RalphChapin

1

我想寫一個函數,它使用UTF-8編碼將Java對象序列化爲字符串。

是...好你的代碼是什麼實際上做的是序列化對象的字節,然後告訴String構造「這些字節是一些Unicode代碼點的有效UTF-8編碼」。問題是(一般來說)它們不是......並且當UTF-8解碼器試圖將它們轉換爲Java字符串中使用的UTF-16表示時,它會查找無效的序列並用「無效字符「碼點。

如果要將任意字節表示爲Java字符串,則需要使用類似base64編碼的內容。更好的辦法是將字節作爲Blob放入數據庫中。

相關問題