您好,登錄后才能下訂單哦!
本篇內容介紹了“C#從UTF-8流中讀取字符串的正確方法是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
我們下面的代碼是從一個流 stream 中讀取 UTF-8 編碼的字符串。我們可以先考慮一下其中存在的潛在問題。
string ReadString(Stream stream) { var sb = new StringBuilder(); var buffer = new byte[4096]; int readCount; while ((readCount = stream.Read(buffer)) > 0) { var s = Encoding.UTF8.GetString(buffer, 0, readCount); sb.Append(s); } return sb.ToString(); }
問題出在:某些情況下返回的字符串與與原始編碼的字符串并不同。
例如,笑臉符號???? 有時會被解碼為 4 個未知字符:
編碼字符串: ????
解碼字符串: ????
我們知道:UTF-8 可以使用 1 到 4 個字節來表示一個 Unicode 字符,有關字符串編碼的知識可以參考 字符編碼 一文。
Stream.Read 方法可以把從 1 到 messageBuffer.Length 字節返回,這意味著緩沖區可能包含不完整的 UTF-8 字符。
一旦緩沖區中的最后一個字符的 UTF-8 編碼不完整,那么 Encoding.UTF8.GetString 就是轉換一個無效的 UTF-8 字符串。在這種情況下,該方法返回一個無效字符串,因為它無法猜測丟失的字節。
我們使用以下代碼演示以上行為:
var bytes = Encoding.UTF8.GetBytes("?"); // bytes = new byte[4] { 240, 159, 152, 138 } var sb = new StringBuilder(); // 模擬逐個字節地讀取數據流 for (var i = 0; i < bytes.Length; i++) { sb.Append(Encoding.UTF8.GetString(bytes, i, 1)); } Console.WriteLine(sb.ToString()); // "????" 代替了 "????" Encoding.UTF8.GetBytes(sb.ToString()); // new byte[12] { 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189 }
有多種方法可以修復代碼。
第一種方法:只有當你得到全部數據時,才將字節數組轉換為字符串。
string ReadString(Stream stream) { using var ms = new MemoryStream(); var buffer = new byte[4096]; int readCount; while ((readCount = stream.Read(buffer)) > 0) { ms.Write(buffer, 0, readCount); } return Encoding.UTF8.GetString(ms.ToArray()); }
第二種方法:可以把流包進一個具有正確編碼的 StreamReader 對象中。
string ReadString(Stream stream) { using var sr = new StreamReader(stream, Encoding.UTF8); return sr.ReadToEnd(); }
另外,還可以使用System.Text.Decoder類來正確解碼緩沖區內的字符。在需要性能的情況下,可以使用PipeReader、Rune類來以內存優化的方式讀取數據。
“C#從UTF-8流中讀取字符串的正確方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。