繁体   English   中英

File.Copy 和字符编码

[英]File.Copy and character encoding

我注意到 .NET 3.5SP1 中File.Copy()的一个奇怪行为。 我不知道这是错误还是功能。 但我知道这让我发疯。 我们在自定义构建步骤中使用File.Copy() ,它搞砸了字符编码。

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

这是要重现的代码。 我首先将一个 UTF-8 文件复制到目标位置,然后将一个 ANSI 文件复制到同一目标位置。 注意第二个控制台的output output: 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 混淆

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

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

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

来自 StreamReader 的文档:

此构造函数将编码初始化为 UTF8Encoding,使用 stream 参数初始化 BaseStream 属性,并将内部缓冲区初始化为默认大小。

detectEncodingFromByteOrderMarks 参数通过查看 stream 的前三个字节来检测编码。如果文件以适当的字节顺序标记开头,它会自动识别 UTF-8、小端 Unicode 和大端 Unicode 文本。 有关详细信息,请参阅 Encoding.GetPreamble 方法。

现在File.Copy只是将原始字节从一个地方复制到另一个地方——它不应该改变任何字符编码,因为它首先不会尝试将文件解释为文本文件。

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

  • File.Copy根本不应该改变文件的内容
  • StreamReader只能检测UTF-8和UTF-16; 如果你需要读取一个用任何其他编码编码的文件,你应该在构造函数中显式地使用 state。 (顺便说一句,我个人建议使用Encoding.Default而不是Encoding.GetEncoding(0) 。我认为这样更清楚。)

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM