0

ファイルのエンコーディングについて少し混乱しています。変えたい。これが私のコードです:

public class ChangeFileEncoding
    {
        private const int BUFFER_SIZE = 15000;

        public static void ChangeEncoding(string source, Encoding destinationEncoding)
        {
            var currentEncoding = GetFileEncoding(source);
            string destination = Path.GetDirectoryName(source) +@"\"+ Guid.NewGuid().ToString() + Path.GetExtension(source);
            using (var reader = new StreamReader(source, currentEncoding))
            {
                using (var writer =new StreamWriter(File.OpenWrite(destination),destinationEncoding ))
                {
                    char[] buffer = new char[BUFFER_SIZE];
                    int charsRead;
                    while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        writer.Write(buffer, 0, charsRead);                        
                    }
                }
            }
            File.Delete(source);
            File.Move(destination, source);
        }

        public static Encoding GetFileEncoding(string srcFile)
        {
            using (var reader = new StreamReader(srcFile))
            {
                reader.Peek();
                return reader.CurrentEncoding;
            }
        }
    }

Program.cs には次のコードがあります。

    string file = @"D:\path\test.txt";
    Console.WriteLine(ChangeFileEncoding.GetFileEncoding(file).EncodingName);
    ChangeFileEncoding.ChangeEncoding(file, new System.Text.ASCIIEncoding());
    Console.WriteLine(ChangeFileEncoding.GetFileEncoding(file).EncodingName);

そして、コンソールに表示されるテキストは次のとおりです。

ユニコード (UTF-8)

ユニコード (UTF-8)

ファイルのエンコーディングが変更されていないのはなぜですか? ファイルのエンコーディングを変更するのは間違っていますか?

よろしく

4

2 に答える 2

1

StreamReader クラスは、コンストラクターで Encoding が渡されない場合、ファイルのエンコーディングを自動的に検出しようとします。ファイルが BOM で始まる場合は問題ありません (次にファイルを読みたいときにこれを容易にするために、ファイルのエンコーディングを変更するときにプリアンブルを記述する必要があります)。

テキスト ファイルのエンコーディングを適切に検出することは、特に非 Unicode ファイルまたは BOM のない Unicode ファイルの場合、困難な問題です。リーダー (StreamReader、Notepad++、またはその他のリーダー) は、ファイルで使用されているエンコーディングを推測する必要があります。

テキストファイルのエンコーディング/コードページを検出する方法も参照してください。

コードページを検出できません。通知する必要があります。バイトを分析して推測することはできますが、奇妙な (場合によっては面白い) 結果が得られる可能性があります。

ASCII (文字 0 ~ 127) は Unicode のサブセットであるため、1 バイトの Unicode エンコーディング (UTF-8) で ASCII ファイルを安全に読み取ることができます。したがって、そのエンコーディングを使用する StreamReader 。

つまり、それが本当に ASCII である限り。コード ポイント 127 を超える文字はすべて ANSI であり、正しいコード ページを推測して検出する楽しみに夢中になります。

あなたの質問に答えるために:ファイルのエンコーディング変更しました。それを「検出」する確実な方法はありません。推測するだけです。

必要な読み物:すべてのソフトウェア開発者が Unicode と文字セット (言い訳はありません!)およびUnicode、UTF、ASCII、ANSI 形式の違いについて絶対に、積極的に知っておく必要がある絶対的な最小値.

于 2016-03-11T10:18:08.087 に答える
0

StreamReader.CurrentEncodingファイルがどのエンコーディングを使用しているかはわかりませんが、ファイルを読み取るために必要StreamReaderなエンコーディングはわかりません。基本的に、BOM がない場合、ファイル全体を読み取らずにエンコーディングを検出する簡単な方法はありません (そして、そこにあるものを分析するのは簡単なことではありません)。

BOM のあるファイルの場合は、次のように簡単です。

public static Encoding GetFileEncoding(string srcFile)
{
   var bom = new byte[4];
   using (var f = new FileStream(srcFile, FileMode.Open, FileAccess.Read))
     f.Read(bom, 0, 4);

   if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76) return Encoding.UTF7;
   if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) return Encoding.UTF8;
   if (bom[0] == 0xff && bom[1] == 0xfe) return Encoding.Unicode;
   if (bom[0] == 0xfe && bom[1] == 0xff) return Encoding.BigEndianUnicode;
   if (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff) return Encoding.UTF32;
   // No BOM, so you choose what to return... the usual would be returning UTF8 or ASCII
   return Encoding.UTF8;
}
于 2016-03-11T10:27:32.877 に答える