您好,登录后才能下订单哦!
本篇内容介绍了“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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。