71

ソースファイルにファイルヘッダーが含まれているかどうかをチェックするTFSチェックインポリシーを作成しています。

私の問題は、ファイルヘッダーに特殊文字「©」が含まれていて、残念ながら一部のソースファイルがANSIでエンコードされていることです。したがって、ポリシーでこれらのファイルを読み取ると、文字列は「Copyright�2009」のようになります。

string content = File.ReadAllText(pendingChange.LocalItem);

文字列のエンコーディングを変更するのに疲れましたが、役に立ちません。では、これらのファイルをどのように読み取れば、正しい文字列「Copyright©2009」を取得できますか?

4

3 に答える 3

140

使用Encoding.Default:

string content = File.ReadAllText(pendingChange.LocalItem, Encoding.Default);

ただし、システムのデフォルトのエンコーディングを使用して読み取ることに注意してください。これは、ファイルのエンコーディングとは異なる場合があります。ANSI と呼ばれる単一のエンコーディングはありませんが、通常、人々が「ANSI エンコーディング」について話すときは、Windows Code Page 1252 や、ボックスで使用されているものを意味します。

使用されている正確なエンコーディングを見つけることができれば、コードはより堅牢になります。

于 2009-09-16T10:16:42.373 に答える
6

チームが標準エンコーディングに同意するようなポリシーを作成する場合は、賢明に思われます。正直なところ、どのチームも「Unicode (署名付き UtF-8) - コードページ 65001」以外のエンコーディングを使用する理由がわかりません (おそらく、重要な非ラテン語の静的コンテンツを含む ASPX ページを除きますが、それでも私はできます. UTF-8 を使用することがどれほど大きな問題になるかはわかりません)。

エンコーディングの混在を許可したい場合は、次に、ファイルがどのエンコーディングで保存されたかを判断して、どのエンコーディングに渡すかを知る方法が必要ですReadAllText。ファイルからこれを判断するのは簡単ではありませんが、使用すると問題Encoding.Defaultなく動作する可能性があります。ほとんどの場合、VS (署名付きの UTF-8) とマシンで使用される一般的な ANSI エンコーディング (おそらく Windows-1252) の 2 つのエンコーディングしか使用できません。

したがって、

 string content = File.ReadAllText(pendingChange.LocalItem, Encoding.Default);

動作します。(私が見るように、ジョンはすでに投稿しています)。これは、UTF-8 BOM (VS が「署名」という用語で意味するもの) がファイルの先頭にある場合、指定されたエンコーディング パラメーターが無視され、とにかく UTF-8 が使用されるためです。したがって、ファイルが UTF-8 を使用して保存されている場合は正しい結果が得られ、ANSI が使用されている場合も正しい結果が得られる可能性が高くなります。

ところで、ファイル ヘッダーを処理している場合、作業はReadAllLines簡単になりませんか?.

于 2009-09-16T10:42:25.450 に答える
1

これは古い質問であることは知っていますが、同様の状況に遭遇し、受け入れられた回答がいくつかのコーナーをカットしていることがわかりました(Jon Skeetの実用的な短い回答を無視しませんが、もう少し肉付けします)...

仕様では、ヘッダーの直後にエンコーディングが含まれると記載されています{\rtf:

\ansi ANSI (デフォルト)
 \mac アップル マッキントッシュ
 \pc IBM PC コード ページ 437
 \pca IBM PC コード ページ 850、IBM Personal System/2 で使用 (Microsoft Word for OS/2 のバージョン 1 には実装されていません)

ウィキペディアによると、「ANSI 文字セットには明確な意味がありません

デフォルトの ANSI では、これらの部分的に互換性のないエンコーディングを選択できます。

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 : 指定された文字セットに基づく 16 進値 (8 ビット値の識別に使用される場合があります)。

{\rtf1\ansi\ansicpg1252ファイルが で始まる場合は、ヘッダーを読み取るのが最善の方法だと思いますWindows-1252

しかし、事態をさらに複雑にするために、仕様にはエンコーディングが混在する可能性があることも記載されています...「\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);
于 2021-04-05T00:49:26.957 に答える