C#编码

在本文中,我们展示了如何在C#中编码和解码数据。

Unicode是一种计算行业标准,用于对世界上大多数书写系统中表达的文本进行一致的编码、表示和处理。

在C#中,字符串是Unicode字符的序列。它是一种存储数据值序列的数据类型,通常是字节,其中元素通常根据字符编码代表字符。C#内部使用UTF-16编码。

编码是将一组Unicode字符转换为字节序列的过程。解码是相反的过程;它将一系列编码字节转换为一组Unicode字符。

.NET中提供了标准字符编码:ASCII、UTF-7(已弃用)、UTF-8、UTF-16和UTF-32。

System.Text.Encoding类在.NET中用于编码和解码过程。.NET内部使用UTF-16字符编码。它在Encoding.Unicode下可用。

C#编码获取字节数

GetByteCount方法返回编码指定字符产生的字节数。

using System.Text;

string text = "one 🐘 and three 🐋";

int n = Encoding.UTF8.GetByteCount(text);
Console.WriteLine($"UTF-8: {n}");

n = Encoding.UTF32.GetByteCount(text);
Console.WriteLine($"UTF-32: {n}");

n = Encoding.Unicode.GetByteCount(text);
Console.WriteLine($"UTF-16: {n}");

n = Encoding.BigEndianUnicode.GetByteCount(text);
Console.WriteLine($"UTF-16BE: {n}");

n = Encoding.Latin1.GetByteCount(text);
Console.WriteLine($"Latin1: {n}");

n = Encoding.ASCII.GetByteCount(text);
Console.WriteLine($"ASCII: {n}");

该示例打印给定字符串以指定编码编码时产生的字节数。

$ dotnet run
UTF-8: 23
UTF-32: 68
UTF-16: 38
UTF-16BE: 38
Latin1: 19
ASCII: 19

C#编码获取字节

GetBytes方法返回一个字节数组,其中包含对指定字符集进行编码的结果。

using System.Text;

string text = "one 🐘 and three 🐋";

Console.WriteLine("UTF-8 bytes");
byte[] uft8Data = Encoding.UTF8.GetBytes(text);
showBytes(uft8Data);

Console.WriteLine("UTF-16 bytes");
byte[] uft16Data = Encoding.Unicode.GetBytes(text);
showBytes(uft16Data);

Console.WriteLine("UTF-16BE bytes");
byte[] uft16BEData = Encoding.BigEndianUnicode.GetBytes(text);
showBytes(uft16BEData);

Console.WriteLine("Latin1 bytes");
byte[] latin1Data = Encoding.Latin1.GetBytes(text);
showBytes(latin1Data);

void showBytes(byte[] data)
{
    int i = 0;

    foreach (var e in data)
    {
        Console.Write($"{e.ToString("X4")} ");
        i++;

        if (i % 10 == 0)
        {
            Console.WriteLine();
        }
    }

    Console.WriteLine();
}

该示例将给定的字符串编码为UTF-8、UTF-16、UTF-16BE和Latin1编码的字节。

$ dotnet run
UTF-8 bytes
006F 006E 0065 0020 00F0 009F 0090 0098 0020 0061
006E 0064 0020 0074 0068 0072 0065 0065 0020 00F0
009F 0090 008B
UTF-16 bytes
006F 0000 006E 0000 0065 0000 0020 0000 003D 00D8
0018 00DC 0020 0000 0061 0000 006E 0000 0064 0000
0020 0000 0074 0000 0068 0000 0072 0000 0065 0000
0065 0000 0020 0000 003D 00D8 000B 00DC
UTF-16BE bytes
0000 006F 0000 006E 0000 0065 0000 0020 00D8 003D
00DC 0018 0000 0020 0000 0061 0000 006E 0000 0064
0000 0020 0000 0074 0000 0068 0000 0072 0000 0065
0000 0065 0000 0020 00D8 003D 00DC 000B
Latin1 bytes
006F 006E 0065 0020 003F 003F 0020 0061 006E 0064
0020 0074 0068 0072 0065 0065 0020 003F 003F

C#编码获取字符串

GetString方法构建一个字符串,其中包含解码指定字节序列的结果。

using System.Text;

string text = "one 🐘 and three 🐋";

Console.WriteLine("UTF-8 bytes");
byte[] uft8Data = Encoding.UTF8.GetBytes(text);
string output = Encoding.UTF8.GetString(uft8Data);
Console.WriteLine(output);

Console.WriteLine("UTF-16 bytes");
byte[] uft16Data = Encoding.Unicode.GetBytes(text);
output = Encoding.Unicode.GetString(uft16Data);
Console.WriteLine(output);

Console.WriteLine("UTF-16BE bytes");
byte[] uft16BEData = Encoding.BigEndianUnicode.GetBytes(text);
output = Encoding.BigEndianUnicode.GetString(uft16BEData);
Console.WriteLine(output);

Console.WriteLine("Latin1 bytes");
byte[] latin1Data = Encoding.Latin1.GetBytes(text);
output = Encoding.Latin1.GetString(latin1Data);
Console.WriteLine(output);

在示例中,我们首先使用GetBytes将给定的字符串编码为字节数组。稍后,我们使用GetString将字节解码为字符串。我们使用四种不同的编码。

$ dotnet run
UTF-8 bytes
one 🐘 and three 🐋
UTF-16 bytes
one 🐘 and three 🐋
UTF-16BE bytes
one 🐘 and three 🐋
Latin1 bytes
one ?? and three ??

Latin1编码不适用于表情符号。

C#编码.转换

Encoding.Convert方法将整个字节数组从一种编码转换为另一种编码。

using System.Text;

string text = "one 🐘 and three 🐋";

byte[] utf16Data = Encoding.Unicode.GetBytes(text);
byte[] utf8Data = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Data);

Console.WriteLine("UTF-16 bytes");
showBytes(utf16Data);

Console.WriteLine();

Console.WriteLine("UTF-8 bytes");
showBytes(utf8Data);

Console.WriteLine();
string output = Encoding.UTF8.GetString(utf8Data);
Console.WriteLine(output);


void showBytes(byte[] data)
{
    int i = 0;

    foreach (var e in data)
    {
        Console.Write($"{e.ToString("X4")} ");
        i++;

        if (i % 10 == 0)
        {
            Console.WriteLine();
        }
    }

    Console.WriteLine();
}

在示例中,我们将UTF-16字节转换为UTF-8字节。

$ dotnet run
UTF-16 bytes
006F 0000 006E 0000 0065 0000 0020 0000 003D 00D8 
0018 00DC 0020 0000 0061 0000 006E 0000 0064 0000 
0020 0000 0074 0000 0068 0000 0072 0000 0065 0000 
0065 0000 0020 0000 003D 00D8 000B 00DC 

UTF-8 bytes
006F 006E 0065 0020 00F0 009F 0090 0098 0020 0061 
006E 0064 0020 0074 0068 0072 0065 0065 0020 00F0 
009F 0090 008B 

one 🐘 and three 🐋

使用编码的C#读/写数据

接下来,我们将数据写入文件并使用指定的编码从中读取。

using System.Text;

string text = "one 🐘 and three 🐋";

using var fs = new FileStream("data.txt", FileMode.OpenOrCreate);
using var sw = new StreamWriter(fs, Encoding.UTF8);
sw.Write(text);

在示例中,我们使用Encoding.UTF8将文本写入文件。

using var sw = new StreamWriter(fs, Encoding.UTF8);

StreamWriter的第二个参数是要使用的字符编码。

$ dotnet run
$ file data.txt 
data.txt: Unicode text, UTF-8 (with BOM) text, with no line terminators
$ cat data.txt 
one 🐘 and three 🐋

接下来,我们从文件中读取数据。

using System.Text;

using var fs = new FileStream("data.txt", FileMode.Open);
using var sr = new StreamReader(fs, Encoding.UTF8);

string? text = sr.ReadLine();
Console.WriteLine(text);

我们使用StreamReader来读取数据;我们在第二个参数中指定字符编码。

$ dotnet run
one 🐘 and three 🐋

在本文中,我们使用C#编码和解码数据。

列出所有C#教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏