91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#從UTF-8流中讀取字符串的正確方法是什么

發布時間:2021-11-22 09:37:59 來源:億速云 閱讀:143 作者:iii 欄目:開發技術

本篇內容介紹了“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流中讀取字符串的正確方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙陵县| 同德县| 聊城市| 石河子市| 深州市| 达日县| 恩平市| 白山市| 怀仁县| 锡林郭勒盟| 达拉特旗| 广昌县| 汉川市| 翼城县| 巨野县| 饶阳县| 内黄县| 大渡口区| 广饶县| 永兴县| 冕宁县| 遵义市| 益阳市| 武冈市| 西乡县| 贺州市| 凤城市| 宾川县| 思南县| 义乌市| 拜城县| 大同市| 贵南县| 安庆市| 五大连池市| 桓台县| 瑞昌市| 中江县| 兰西县| 宝丰县| 延安市|