服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# 从 UTF-8 流中读取字符串的正确方法及代码详解

C# 从 UTF-8 流中读取字符串的正确方法及代码详解

2022-12-09 12:26wanghao72214 C#

在本篇文章里小编给大家整理的是一篇关于C# 从 UTF-8 流中读取字符串的正确方法的知识点内容,有兴趣的朋友们可以学习参考下。

 我们下面的代码是从一个流 stream 中读取 UTF-8 编码的字符串。我们可以先考虑一下其中存在的潜在问题。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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();
}

问题出在:某些情况下返回的字符串与与原始编码的字符串并不同。

例如,笑脸符号 C# 从 UTF-8 流中读取字符串的正确方法及代码详解有时会被解码为 4 个未知字符:

编码字符串:C# 从 UTF-8 流中读取字符串的正确方法及代码详解
解码字符串: ????

我们知道:UTF-8 可以使用 1 到 4 个字节来表示一个 Unicode 字符,有关字符串编码的知识可以参考 ​​字符编码​​​ 一文。

​​Stream.Read​​​ 方法可以把从 1 到​​ messageBuffer.Length​​​ 字节返回,这意味着缓冲区可能包含不完整的 UTF-8 字符。

一旦缓冲区中的最后一个字符的 UTF-8 编码不完整,那么 ​​Encoding.UTF8.GetString​​ 就是转换一个无效的 UTF-8 字符串。在这种情况下,该方法返回一个无效字符串,因为它无法猜测丢失的字节。

我们使用以下代码演示以上行为:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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());
// "????" 代替了 "C# 从 UTF-8 流中读取字符串的正确方法及代码详解"
 
Encoding.UTF8.GetBytes(sb.ToString());
// new byte[12] { 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189 }

如何修复代码

有多种方法可以修复代码。

第一种方法:只有当你得到全部数据时,才将字节数组转换为字符串。

?
1
2
3
4
5
6
7
8
9
10
11
12
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 对象中。

?
1
2
3
4
5
string ReadString(Stream stream)
{
    using var sr = new StreamReader(stream, Encoding.UTF8);
    return sr.ReadToEnd();
}

另外,还可以使用System.Text.Decoder类来正确解码缓冲区内的字符。在需要性能的情况下,可以使用PipeReader、Rune类来以内存优化的方式读取数据。

到此这篇关于C# 从 UTF-8 流中读取字符串的正确方法及代码详解的文章就介绍到这了,更多相关C# 从 UTF-8 流中读取字符串的正确方法内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/wanghao72214/p/15586846.html

延伸 · 阅读

精彩推荐
  • C#C#实现飞行棋项目

    C#实现飞行棋项目

    这篇文章主要为大家详细介绍了C#实现飞行棋项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    氪金万岁~11062022-08-24
  • C#C# 泛型接口的抗变和协变

    C# 泛型接口的抗变和协变

    本篇文章主要介绍了C#中泛型接口的抗变和协变的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧...

    醉秋风9762021-12-30
  • C#C#实现类似jQuery的方法连缀功能

    C#实现类似jQuery的方法连缀功能

    这篇文章主要介绍了C#实现类似jQuery的方法连缀功能,可以简化语句,使代码变得清晰简单,感兴趣的小伙伴们可以参考一下...

    JackWang-CUMT4762021-11-02
  • C#C#合并BitMap图像生成超大bitmap

    C#合并BitMap图像生成超大bitmap

    当两个图像合并的时候,以简单的使用gdi+,当需要将许多bitmap合并时就会造成宽度过大,那么怎么实现C#合并BitMap图像,本文就详细的介绍一下...

    记住我Gxy8322022-12-08
  • C#c# 如何使用 My 命名空间

    c# 如何使用 My 命名空间

    这篇文章主要介绍了c# 如何使用 My 命名空间,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...

    olprod4612022-10-11
  • C#C#/VB.NET 自定义PPT动画路径的步骤

    C#/VB.NET 自定义PPT动画路径的步骤

    这篇文章主要介绍了C#/VB.NET 自定义PPT动画路径的步骤,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...

    E-iceblue6532022-11-16
  • C#c# Parallel类的使用

    c# Parallel类的使用

    这篇文章主要介绍了c# Parallel类的使用,帮助大家实现数据与任务的并行,感兴趣的朋友可以了解下...

    一只独行的猿11882022-10-17
  • C#C# web.config之<customErrors>节点说明案例详解

    C# web.config之<customErrors>节点说明案例详解

    这篇文章主要介绍了C# web.config之<customErrors>节点说明案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可...

    烈日轨迹8242022-12-01