C# 我的应用程序的内部编码

C# 我的应用程序的内部编码,c#,unicode,encoding,utf-8,utf-16,C#,Unicode,Encoding,Utf 8,Utf 16,我的桌面c#应用程序从用户那里获取各种文档,可能采用不同的编码 我需要向用户显示现有文档,允许在我的UI中操作它们,并存储它们以备将来使用 在我看来,将“编码”的概念添加到这些步骤中似乎很复杂。我想在内部总是将用户输入文档转换为UTF-8,因此我的UI和数据存储不需要担心它。然后,当用户希望将文档作为文件返回时,我会询问用户使用哪种编码 这有意义吗?编码是否可互操作?如果我只支持unicode怎么办?编码是不可互操作的,因为有些编码具有其他编码不具有的字符 Unicode内部表示是一个好主意,因

我的桌面c#应用程序从用户那里获取各种文档,可能采用不同的编码

我需要向用户显示现有文档,允许在我的UI中操作它们,并存储它们以备将来使用

在我看来,将“编码”的概念添加到这些步骤中似乎很复杂。我想在内部总是将用户输入文档转换为UTF-8,因此我的UI和数据存储不需要担心它。然后,当用户希望将文档作为文件返回时,我会询问用户使用哪种编码


这有意义吗?编码是否可互操作?如果我只支持unicode怎么办?

编码是不可互操作的,因为有些编码具有其他编码不具有的字符


Unicode内部表示是一个好主意,因为它具有更宽的字符集,但是如果添加的字符仍在所述编码中,我建议以原始编码保存文档。如果没有,请提示用户您将保存为Unicode,以便正确编码这些字符。

在应用程序中,您应该使用本机Unicode支持(平台用于存储Unicode的内容)。在Windows和OS X上,这是一种
UTF-16
,但在Linux上则是
UTF-8

当涉及到保存/加载文件或与外部系统通信时,请选择
UTF-8

另外,不要将代码页与编码混淆


关于代码页,今天我认为支持它们不再那么重要了。至少这不应该是你的优先事项。因为对于ANSI编码,您没有BOM,因此很难猜测文件的编码(事实上,不可能做到完美)

只需将所有文档解码为
字符串
。Net中的字符串始终是Unicode(utf-16)。只有在读取或写入文件时才使用编码。

当您获得ANSI文件时,在转换为unicode e之前,您应该知道代码页。G创建utf-16字符串,否则从128到255的字节可能会导致错误的unicode代码点。当您想将unicode字符串存储到ANSI文件时,您可能会遇到麻烦,因为高达0x10ffff的代码点无法装入单个字节。

在交换格式中使用UTF-16只有两个原因(即从a发送到B的原因):

  • 您没有设计文档类型,必须与已经使用它的东西进行互操作
  • 您的内容是这样的,在某些语言中UTF-16更短。这是相对罕见的,因为即使使用这些语言,混合中也经常有大量来自BMP的字符,因此UTF-8最终更加简洁
  • 除此之外,只有两个理由可以在交换格式中使用UTF-8以外的任何东西:

  • 您没有设计文档类型,必须与已经使用旧字符集的内容进行互操作
  • 你讨厌别人
  • 如果你特别讨厌外国人和不使用自己语言的人,那么第二个问题就特别紧迫。但是如果你只是一般地讨厌别人,你会让足够多的人头疼,你会觉得这项运动很令人满意

    现在,从这一点扩展,如果其他人设计的给定文档格式允许UTF-8,并且您可以期望所有处理它的现代软件都能够处理UTF-8,那么有两个原因不这样做:

  • 对数据进行某种类型的安全检查,以确保其未被更改(注意,如果您以任何方式编辑或更改文档,这一点本质上不适用)
  • 你讨厌别人。再次为仇外者提供奖励
  • 对于您的内部存储,这只是一个对您最有用的问题。通常,.NET在内存中时倾向于默认为UTF-16(字符和字符串可以使用它),在写入和读取字符串时倾向于默认为UTF-8。如果您的备份存储是SQL Server,那么UTF-16就是您的朋友(“nchar”、“nvarchar”、“ntext”是“char”、“varchar”、“text”的变体,以避免字符集设置为UTF-8以外的任何字符集时出现问题),其他数据库要么有自己处理现代字符的方法,要么可以使用UTF-8


    但是,一般来说,除非有人强迫你使用UTF-8(因为他们被迫处理90年代或更早时期的代码,或者因为他们讨厌人)。

    那么UTF-8和UTF-16是可互操作的吗?假设我只关心unicode,我可以立即将每个输入文档转换为utf-8,我所有的内部UI控件和DB都将使用它。然后,当用户想要导出回来时,我可以再次询问使用哪种编码(或者在将来通过使用“原始编码”字段为用户节省一些工作)。这有意义吗?但是utf8和utf16是可互操作的。如果您将文档转换为unicode,这意味着您知道它们的编码,因此您可以将其保存在“原始编码”字段中。“可互操作”并不完全正确,因为确实需要显式转换。不过,它们是可循环的,因为每个有效的UTF-8流都可以转换为UTF-16,然后再转换回来而不会丢失,反之亦然。utf8everywhere.org。关于编码没什么可说的了。