我正在编写TFS Checkin策略,该策略检查我们的源文件是否包含我们的文件头。
我的问题是,我们的文件头包含一个特殊字符“©”,不幸的是我们的一些源文件是用ANSI编码的。 因此,如果我在策略中阅读这些文件,则字符串看起来像“Copyright 2009”。
string content = File.ReadAllText(pendingChange.LocalItem);
我厌倦了改变字符串的编码,但它没有帮助。那么如何阅读这些文件,我得到正确的字符串“Copyright©2009”?
感谢您的帮助!
关心恩伊
答案 0 :(得分:118)
使用Encoding.Default
:
string content = File.ReadAllText(pendingChange.LocalItem, Encoding.Default);
但是,您应该知道,它使用系统默认编码来读取它 - 这可能与文件的编码不同。没有单一的编码称为ANSI,但通常是,当人们谈论“ANSI编码”时,他们指的是Windows代码页或者他们的盒子碰巧使用的。
如果您能找到所使用的完全编码,您的代码将更加强大。
答案 1 :(得分:5)
如果你有这样的政策,你也会有团队认可的标准编码,这似乎是明智的。说实话,我不明白为什么任何团队都会使用除“Unicode(带签名的UtF-8) - 代码页65001”以外的编码(除非ASPX页面具有显着的非拉丁静态内容,但即便如此我也可以'看看使用UTF-8是多么重要。
假设您仍然希望允许混合编码,那么您接下来需要一种方法来确定保存文件的编码,以便您知道要传递给ReadAllText
的编码。从文件中确定这一点并不容易,但使用Encoding.Default
可能会正常工作。因为它很可能只有2个编码来处理,VS(带签名的UTF-8)和你的机器使用的常见ANSI编码(可能是Windows-1252)。
因此使用
string content = File.ReadAllText(pendingChange.LocalItem, Encoding.Default);
会奏效。 (正如我看到Jon已经发布的那样)。这是有效的,因为当UTF-8 BOM(这是VS的术语“签名”)在文件的开头出现时,忽略提供的编码参数,无论如何都使用UTF-8。因此,在使用UTF-8保存文件的位置,您可以获得正确的结果,并且在使用ANSI的情况下,您很可能也能获得正确的结果。
顺便说一句,如果您正在处理文件头,ReadAllLines
会不会让事情变得更容易?
答案 2 :(得分:0)
我知道这是一个老问题,但我遇到了类似的情况,发现公认的答案是在偷工减料(不考虑乔恩·斯基特务实的简短回答,但我会再充实一点)。 .
specs 声明标头将直接包含在 {\rtf:
之后的编码
\ansi ANSI (the default) \mac Apple Macintosh \pc IBM PC code page 437 \pca IBM PC code page 850, used by IBM Personal System/2 (not implemented in version 1 of Microsoft Word for OS/2)
根据维基百科,“ANSI character set has no well-defined meaning”
对于默认的 ANSI,您可以选择这些 partially incompatible 编码:
using System.Text;
...
string content = File.ReadAllText(filename, Encoding.GetEncoding("ISO-8859-1"));
or
string content = File.ReadAllText(filename, Encoding.GetEncoding("Windows-1252"));
在 Windows 10 上使用写字板保存带有欧元符号的文件(Windows-1252 中为 0x80,ISO-8859-1 中为 0xA4)显示以下内容:
标头在 \ansi
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1043{ ...
并且没有直接使用编码,而是封装在 RTF 编码中:\'80
根据规格:
<块引用>\'hh :十六进制值,基于指定的字符集(可能 用于识别 8 位值)。
我想最好的做法是阅读标题,如果文件以 {\rtf1\ansi\ansicpg1252
开头,则选择 Windows-1252
。
但为了让事情变得更复杂,the specs 还声明可能存在混合编码...搜索 '\upr'...
我想没有明确的答案,在您的情况下,最简单的方法可能是搜索(在未解码的原始字节数组中)您可能在源代码库中遇到的编码版权标志的所有变体.
就我而言,我最终决定也削减一些角落,但添加一小部分防御性编码。到目前为止,我看到的所有文件都是 Windows-1252
,因此我对此进行了通用案例优化。
Encoding encoding = Encoding.GetEncoding("Windows-1252", EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback);
using (System.IO.StreamReader reader = new System.IO.StreamReader(filename, encoding)) {
string header= reader.ReadLine();
if (!header.Contains("cpg1252")) {
if(header.Contains("\\pca"))
encoding = Encoding.GetEncoding(850, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback);
else if (header.Contains("\\pc"))
encoding = Encoding.GetEncoding(437, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback);
else
encoding = Encoding.GetEncoding("ISO-8859-1", EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback);
}
}
string content = System.IO.File.ReadAllText(filename, encoding);