强制C#使用ASCII

我正在使用C#编写应用程序,需要从特定的数据文件格式进行读写。 目前唯一的问题是格式使用严格的单字节字符,当我使用writer和char数组(其中文件大小加倍,以及其他严重问题)时,C#一直试图抛出Unicode。 我一直在努力修改代码以使用字节数组,但是在将它们提供给树视图和数据网格控件时会引起一些抱怨,并且它涉及转换等等。

我花了一点时间谷歌搜索,似乎没有一个简单的typedef我可以用来强制char类型为我的程序使用字节,至少不会导致额外的复杂性。

是否有一种简单的方法可以强制C# .NET程序仅使用ASCII而不接触Unicode?

后来,我得到了这个几乎工作。 在BinaryReader / Writers上使用ASCIIEncoding最终修复了大部分问题(一些额外字符被添加到字符串之前发生了一些问题,但我修复了这个问题)。 我有一个最后一个问题,它很小但可能很大:在文件中,一个特定字符(打印为欧元符号)转换为? 当我加载/保存文件。 这在文本中并不是一个问题,但如果它以记录长度发生,它可能会改变大小千字节(显然不是很好)。 我认为它是由编码引起的,但如果它来自文件,为什么它不会回来?

确切的问题/结果如下:

  • 原始文件:0x80(欧元)

  • 编码:** ASCII:0x3F(?)** UTF8:0xC280(A-hat euro)

这些结果都不会起作用,因为文件中的任何位置都可以更改(如果在记录长度int中将80更改为3F,则可能是65 *(256 ^ 3)的差异)。 不好。 我尝试使用UTF-8编码,认为这样可以很好地解决问题,但它现在正在添加第二个字符,这更糟糕。

C#(.NET)将始终使用Unicode作为字符串。 这是设计的。

当您读取或写入文件时,您可以使用StreamReader / StreamWriter设置强制ASCII编码,如下所示:

 StreamReader reader = new StreamReader (fileStream, new ASCIIEncoding()); 

然后只需使用StreamReader阅读。

写作是一样的,只需使用StreamWriter。

.NET中的Interally字符串总是Unicode,但实际上你不应该对它感兴趣。 如果您需要遵循特定的格式,那么您关闭的路径(以字节forms读取)是正确的。 您只需使用System.Encoding.ASCII类从string->byte[]byte[]->string

如果您的文件格式将单字节字符中的文本与长度,控制字符等二进制值混合使用,则使用的良好编码是代码页28591 aka Latin1 aka ISO-8859-1。

您可以使用以下最具可读性的编码来获取此编码:

 Encoding.GetEncoding(28591) Encoding.GetEncoding("Latin1") Encoding.GetEncoding("ISO-8859-1") 

此编码具有一个有用的特性,即最多255的字节值将转换为未更改为具有相同值的unicode字符(例如,字节0x80变为字符0x0080)。

在您的方案中,这可能比ASCII编码(将0x80到0xFF范围内的值转换为’?’)或任何其他常用编码更有用,这些编码也会转换此范围内的某些字符。

如果你想在.NET中使用它,你可以使用F#来创建一个支持它的库。 F#支持ASCII字符串,字节数组作为基础类型,请参阅文字(F#) (MSDN):

 let asciiString = "This is a string"B