【问题标题】:How do I read and write smart quotes (and other silly characters) in C#如何在 C# 中读写智能引号(和其他愚蠢的字符)
【发布时间】:2012-11-18 06:18:44
【问题描述】:

我正在编写一个程序,它将文件中的所有文本读入一个字符串,在该字符串上循环查看字符,然后使用 Stringbuilder 将字符附加回另一个字符串。我遇到的问题是当它被写回时, 等特殊字符看起来像 � 字符。我不需要进行转换,我只是希望它以我阅读的方式写回:

    StringBuilder sb = new StringBuilder();
    string text = File.ReadAllText(filePath);
    for (int i = 0; i < text.Length; ++i) {
        if (text[i] != '{') {  // looking for opening curly brace
            sb.Append(text[i]);
            continue;
        }
        // Do stuff
    }
    File.WriteAllText(destinationFile, sb.ToString());

我尝试使用不同的编码(UTF-8、UTF-16、ASCII),但结果变得更糟;我开始得到问号符号和汉字(是的,有点像霰弹枪的方法,但我只是在试验)。 我确实读过这篇文章:http://www.joelonsoftware.com/articles/Unicode.html ...但它并没有真正解释为什么我会看到我所看到的,除非在 C# 中,当读者遇到这样的奇怪字符时会开始切断位。提前感谢您的帮助!

【问题讨论】:

  • 如果你调试它并跳过 File.ReadAllText 行,'text' 变量是否有正确的数据,还是有问题?
  • 我发布了一些想法作为潜在答案。请看看,让我知道你发现了什么......
  • @taylorjonl 很奇怪,所有非 utf-8 字符都有一个 � 字符

标签: c# unicode encoding ascii stringbuilder


【解决方案1】:

文本可能是 UTF8。

File.ReadAllText(filePath, Encoding.UTF8)

加上

File.WriteAllText(destinationFile, sb.ToString(), Encoding.UTF8)

应该覆盖掉处理 Unicode 字符。如果你做其中一个或另一个,你将得到垃圾输出,要么两者兼而有之,要么什么都没有。

【讨论】:

    【解决方案2】:

    TL;DR 绝对不是 UTF-8,您甚至没有使用 UTF-8 来读取结果文件。读为Windows1252,写为Windows1252(如果要使用相同的查看方式查看生成的文件)


    首先让我们说普通用户创建的文件不可能是 UTF-8 格式。并非 Windows 中的所有程序都支持它(excel、记事本..),更不用说将其作为默认编码(甚至大多数 developer 工具也不默认为 utf-8,这让我发疯了)。既然很多开发者都不明白编码这种东西的存在,那么普通用户有多少机会将他们的文件保存在 utf-8 恶意环境中呢?

    这是您的问题首先开始的地方。根据documentation 的说法,你使用的重载File.ReadAllText(filePath); 只能检测到UTF-8 或UTF-32。

    确实,只需读取在 Windows-1252 中正常编码且包含 "a”a" 的文件,就会得到一个字符串 "a�a",其中 unicode replacement character(阅读 wikipedia 部分,它准确地描述了您所处的情况in!) 用于替换无效字节。当替换字符再次编码为 UTF-8 并解释为 Windows-1252 时,您将看到 �,因为 UTF-8 中 的字节是 0xEF, 0xBF, 0xBD,它们是 Windows 中 � 的字节-1252.

    因此,将其读为 Windows-1252,您就已经完成了一半:

    Encoding windows1252 = Encoding.GetEncoding("Windows-1252");
    String result = File.ReadAllText(@"C:\myfile.txt", windows1252);
    Console.WriteLine(result); //Correctly prints "a”a" now
    

    因为您看到了�,所以您用来查看新制作文件的工具也是使用 Windows-1252。因此,如果目标是让文件在该工具中显示正确的字符,则必须将输出编码为 Windows-1252:

    Encoding windows1252 = Encoding.GetEncoding("Windows-1252");
    File.WriteAllText(@"C:\myFile", sb.toString(), windows1252);
    

    【讨论】:

    • 哇,谢谢,这是一个非常彻底的答案!也感谢您向我展示这些文章!对不起,如果这个问题有点冗长,只是不想看起来我没有做任何研究。当我有足够的代表这样做时,我会对此表示赞成。
    • 只是杯水车薪,但是,嘿! +1 @Esailija
    • @User1234567890 不,tl;dr 是为了总结我的回答:P
    • 五年后,这仍然是这个问题的最佳答案,只有六个赞成票:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 2016-03-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2015-12-06
    相关资源
    最近更新 更多