我正在使用C#编写应用程序,需要从特定的数据文件格式进行读写。目前唯一的问题是格式使用严格的单字节字符,当我使用writer和char数组时,C#一直试图抛出Unicode(这会使文件大小增加一倍,以及其他严重的问题)。我一直在努力修改代码以使用字节数组,但是在将它们提供给树视图和数据网格控件时会引起一些抱怨,并且它涉及转换等等。
我花了一点时间用Google搜索,似乎没有一个简单的typedef我可以用来强制char
类型为我的程序使用byte,至少不会造成额外的复杂性。
是否有一种简单的方法可以强制C#.NET程序仅使用ASCII而不接触Unicode? p>
后来,我得到了这个几乎工作。在BinaryReader / Writers上使用ASCIIEncoding
最终修复了大部分问题(一些额外字符被添加到字符串之前发生了一些问题,但我修复了这个问题)。我有一个最后一个问题,它很小但可能很大:在文件中,当我加载/保存文件时,特定字符(打印为欧元符号)会转换为?
。这在文本中并不是一个问题,但如果它出现在记录长度上,它可能会改变大小千字节(显然不是很好)。我认为它是由编码引起的,但如果它来自文件,为什么它不会回来?
确切的问题/结果如下:
原始档案:0x80(欧元)
编码: ** ASCII:0x3F(?) ** UTF8:0xC280(A-hat euro)
这些结果都不会起作用,因为文件中的任何位置都可以更改(如果在记录长度int中将80更改为3F,则可能是65 *(256 ^ 3)的差异)。不好。我尝试使用UTF-8编码,认为这样可以很好地解决问题,但它现在正在添加第二个字符,这更糟糕。
答案 0 :(得分:24)
C#(.NET)将始终对字符串使用Unicode。这是设计的。
当您读取或写入文件时,您可以使用StreamReader / StreamWriter设置强制ASCII编码,如下所示:
StreamReader reader = new StreamReader (fileStream, new ASCIIEncoding());
然后只使用StreamReader阅读。
写作是一样的,只需使用StreamWriter。
答案 1 :(得分:5)
.NET中的Interally字符串总是Unicode,但实际上你不应该对它感兴趣。如果您需要遵循特定的格式,那么您关闭的路径(以字节形式读取)是正确的。您只需使用System.Encoding.ASCII
课程即可从string->byte[]
和byte[]->string
进行转化。
答案 2 :(得分:3)
如果你的文件格式将单字节字符中的文本与长度,控制字符等二进制值混合使用,那么使用的好编码是代码页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范围内的值转换为'?')或任何其他常用编码更有用,这些编码也会转换此范围内的某些字符
答案 3 :(得分:0)
如果您想在.NET中使用此功能,则可以使用F#创建支持此功能的库。 F#支持ASCII字符串,以字节数组作为基础类型,请参阅 Literals (F#) (MSDN):
let asciiString = "This is a string"B