2012-02-20 65 views
1

我有一個字節數組作爲輸入。這應該是符合標準的UTF8 HTML的二進制表示。這是,但大部分時間。有時它也包含嵌入的空值(\x0字符或NUL)。這不在我的控制之下。我需要將此字節數組轉換爲字符串。如何將包含零的字節緩衝區轉換爲字符串

到目前爲止已經試過:

  • 顯然使用,因爲它停在打黑第一NUL
  • Encoding.UTF8.GetString無法正常工作或一個StreamReaderTextReader不工作 - 也停在第一NUL

什麼工作,但相當不雅:

mynewarray = myoldarray.Where(x => x!=0).ToArray(); 
    var output = Encoding.UTF8.GetString(mynewarray); 

有沒有更好的方法來做到這一點,除了創建一個新的字節數組跳過NUL字符,然後使用上面的解決方案之一?字節數組可能相當大,超過2-4 Mb ... MSDN指出字符串實際上可能包含嵌入的NUL,但並不知道處理這些字符串的最佳方法是什麼。

+0

事實上,'UTF8.GetString(字節[])'不應該在零點停止.. 。但是在那之後,你確實有一個包含''\ 0''的字符串。 – 2012-02-20 17:32:27

+0

我依賴於斷言的長度屬性,它遠小於緩衝區大小。我需要仔細檢查。 – jdehaan 2012-02-20 18:15:46

+2

如果任何擴展字符在其中,字符串的長度將小於緩衝區大小。 – BlueM 2012-02-20 18:22:20

回答

1

您的字符串已經正確。它將包含NUL字符。但是,當你使用字符串包含NUL字符時,你會遇到各種問題。

Encoding.UTF8.GetString不會停在\ 0處,就像您在我的示例中看到的那樣。

看的時候輸出這樣的字符串會發生什麼:

var text = new byte[]{65, 65, 0, 65}; 
    var s = Encoding.UTF8.GetString(text); 
    Console.WriteLine("len is: " + s.Length + " chars"); 
    Console.WriteLine("text: '" + s + "'");  
    Console.WriteLine("this line doesn't appear because NUL was sent to console"); 

輸出爲:

len is: 4 chars 
text: 'AA 
+0

你完全正確,代碼確實已經在工作......我忽略了由於\ r \ n轉換導致長度不匹配,我錯過了一個數字。長度實際上比原始數組大。我現在就啞巴了。現在感覺有點傻了。然後我可以使用'Replace'方法去除轉換字符串中的'NUL'字符。這使得代碼更安全恕我直言,因爲在某些編碼中,0字節可能是有效的。現在我可以避免在源數組中拋出0字節。 – jdehaan 2012-02-22 09:30:02

0

使用GetString的過載,這需要開始索引和字節數來解碼

var output = Encodeing.UTF8.GetString(mynewarray, 0, mynewarray.Length); 
+0

如果多字節代碼中沒有'\ 0's。 – 2012-02-20 17:26:08

0

您的代碼看起來好像沒什麼問題,但你也許可以通過手動控制的緩衝區來優化它(不確定什麼Where())和/或通過使用不安全的代碼。

指針數學對於通過數組進行快速迭代非常適用,並且您可以完全控制想要提升內存指針的距離(因此它是「不安全的」)。這意味着你可以隨意消費/跳過任何角色。爲了這個目的,我在c#中定期使用優化的緩衝區+不安全的代碼。

.NET框架在適當的地方使用緩衝和不安全的代碼,但由於您知道自己的確切需求,因此您可以調整性能。但是,它會導致更詳細的代碼。

相關問題