2013-05-01 72 views
3

我正在開發一個適應服務器 - 客戶端體系結構的項目。在客戶端和服務器之間傳輸的消息是字符串和字節數組的組合。我需要事先發送整個消息的大小。將字符串寫入套接字的輸出流

查找字節數組的字節大小很簡單,但字符串並非如此。很明顯,我可以將這些字符串轉換爲字節數組(考慮編碼)。但是,這些字符串可能很長,我不想爲它們的副本分配內存(例如getBytes()分配一個新數組)。

我的問題是,進行以下操作的內存效率最高的方法是什麼?字符串的

  1. 查找字節大小(使用UTF-8編碼)
  2. 編寫大小到輸出流
  3. 寫入字符串輸出流
+0

嘗試DataOutputStream。看看javadoc – andy 2013-05-01 14:56:47

+0

@andy我會知道我將要寫入的字符串的大小嗎? – mostruash 2013-05-01 15:00:35

+0

「多久」多久了,您是否真的證明了複製所需的空間/時間是過分的?使用CharsetEncoder來完成此操作可能是可行的(字節計數部分相當簡單),但我認爲在做更復雜的事情之前,儘量證明最簡單的方法是不夠的。 – 2013-05-01 15:03:42

回答

1

迭代由字符串字符字符。請撥打codePointAt()獲取每個位置的Unicode碼點。根據不同的代碼點,你可以推斷出多少字節UTF-8編碼時,將需要:

Codepoint range | UTF-8 bytes 
----------------------------- 
0  - 127  | 1 
128 - 2047 | 2 
2048 - 65535 | 3 
65536 +   | 4 

但你這樣做之前,你應該先驗證這是否是真的有必要。無論如何,傳遞給套接字的字符串很可能在內部複製到字節數組中。

+0

這就是爲什麼我一直在尋找一種方法將字符串寫入一些臨時輸入流,並檢查我寫了多少字節,並將該臨時流傳遞給套接字。如果所有這些都會發生而沒有複製東西......你明白了。 – mostruash 2013-05-01 15:18:41

1

如果大小不是關鍵問題,請對字符串使用UTF16-BE編碼。在這種情況下,大小將爲字符串長度* 2.

在此模式下,您可以逐個編寫Java字符,而無需執行額外的處理(Unicode高低代理等)。

+0

+1年後,你的回答很有用。 – mostruash 2014-09-11 06:52:50

0

您可以隨時在信息包中「分解」您的信息,因此您可以爲信息的某些部分進行計算和內存分配,迭代到另一部分並再次執行。