代码之家  ›  专栏  ›  技术社区  ›  chris166

文件复制和字符编码

  •  0
  • chris166  · 技术社区  · 17 年前

    File.Copy() 在.NET3.5SP1中。我不知道这是一个bug还是一个特性。但我知道这让我发疯。我们使用 在自定义构建步骤中,它会破坏字符编码。

    当我在UTF-8编码的文本文件上复制ASCII编码的文本文件时,目标文件仍然是UTF-8编码的,但具有新文件的内容加上UTF-8的3个前缀字符。这对于ASCII字符是可以的,但是对于ANSI代码页的其余字符(128-255)是不正确的。

    这是要复制的代码。我首先将UTF-8文件复制到目标,然后将ANSI文件复制到同一目标。请注意第二个控制台输出的输出: Content of copy.txt : this is ASCII encoded: / Encoding: utf-8

    File.WriteAllText("ANSI.txt", "this is ANSI encoded: é", Encoding.GetEncoding(0));
    File.WriteAllText("UTF8.txt", "this is UTF8 encoded: é", Encoding.UTF8);
    
    File.Copy("UTF8.txt", "copy.txt", true);
    
    using (StreamReader reader = new StreamReader("copy.txt", true))
    {
        Console.WriteLine("Content of copy.txt : " + reader.ReadToEnd() + " / Encoding: " +
                    reader.CurrentEncoding.BodyName);
    }
    
    File.Copy("ANSI.txt", "copy.txt", true);
    
    using (StreamReader reader = new StreamReader("copy.txt", true))
    {
        Console.WriteLine("Content of copy.txt : " + reader.ReadToEnd() + " / Encoding: " + 
                    reader.CurrentEncoding.BodyName);
    }
    

    你知道为什么会这样吗?我的密码有错误吗?如何解决这个问题的任何想法(我目前的想法是在文件存在之前删除该文件)

    编辑:纠正ANSI/ASCII混淆

    2 回复  |  直到 17 年前
        1
  •  1
  •   Jon Skeet    17 年前

    你在哪里写ASCII.txt?您正在第一行编写ANSI.txt,但这肯定不是ASCII,因为ASCII不包含任何重音字符。ANSI文件将不包含任何表明它是ANSI而不是ASCII或UTF-8的前导。

    基本上,在编写示例的过程中,您似乎已经在ASCII和ANSI之间改变了主意。

    我希望任何ASCII文件都能被“检测”为UTF-8,但编码检测依赖于该文件有一个字节顺序标记,它不是UTF-8。它不像是读取整个文件,然后猜测编码是什么。

    此构造函数初始化 编码为UTF8Encoding时 使用流的BaseStream属性 参数,并将内部缓冲区设置为

    字节顺序标记的检测编码 参数通过以下方式检测编码: 查看 Unicode和大端Unicode文本 如果文件以 适当的字节顺序标记。见 Encoding.GetPreamble方法获取更多信息 信息

    File.Copy 只是将原始字节从一个地方复制到另一个地方-它不应该改变

    我不太清楚您在哪里看到问题(部分原因是ANSI/ASCII部分)。我建议您在您的头脑和问题中,将“File.Copy是否会改变事情?”和“StreamReader检测到什么字符编码”这两个问题分开。答案应该是:

    • 文件,复制
    • StreamReader 只能检测UTF-8和UTF-16;如果需要读取用任何其他编码编码的文件,则应在构造函数中明确说明。(我个人建议使用 Encoding.Default 而不是 Encoding.GetEncoding(0) 顺便说一句我认为这更清楚。)
        2
  •  0
  •   Josh    17 年前

    我怀疑这和File.Copy有关。我认为您看到的是,StreamReader默认使用UTF-8进行解码,而且由于UTF-8是向后兼容的,StreamReader没有任何理由停止使用UTF-8读取ANSI编码的文件。

    如果在十六进制编辑器中打开ASCII.txt和copy.txt,它们是否相同?