2012-05-25 10 views
6

イムを持つファイルを読み込むReadAllTextを使用する方法ReadAllText時にファイルのエンコーディング不明

String[] values = File.ReadAllText(@"c:\\c\\file.txt").Split(';'); 

    int i = 0; 

    foreach (String s in values) 
    { 
     System.Console.WriteLine("output: {0} {1} ", i, s); 
     i++; 
    } 

私は時々(ÖÜÄÀ用...)バック間違った文字を取得するいくつかのファイルを読み込むしようとします。出力は次のようである、そのエンコーディングでいくつかの問題があるため、「?」:

output: 0 TEST 
output: 1 A??O? 

一つの解決策はReadAllTextにエンコーディングを設定することであろう、問題を解決することができReadAllText(@"c:\\c\\file.txt", Encoding.UTF8)ような何かを言うことができます。しかし、もし私がまだ "?"出力として?ファイルのエンコーディングを知らないとどうなりますか? 1つのファイルごとに異なるエンコードがある場合はどうなりますか? C#でそれを行う最善の方法は何でしょうか?確実にこれを行うには

+1

を試してみてください。純粋にファイルの内容に基づいて見つかる100%信頼できる方法はありません。 –

+0

この記事を参照してください http://stackoverflow.com/questions/2239968/c-sharp-file-readalltext-doing-weird-things – Dhaval

答えて

6

唯一の方法は、テキストファイルの先頭にbyte order marksを探すことです、ありがとうございました。 (このブロブは、一般的に、使用される文字エンコーディングのエンディアンを表すだけでなく、エンコーディング(エンコーディング)(UTF8、UTF16、UTF32など)も表します。残念ながら、このメソッドはUnicodeベースのエンコーディングでのみ動作し、その前には何も行われません(信頼性の低いメソッドを使用する必要があります)。

StreamReaderタイプは、エンコーディングを決定するためにこれらのマークを検出サポート - あなたは、単にようなパラメータにフラグを渡す必要があります:あなたはそれまでに使用されるエンコーディングを決定するためにstremReader.CurrentEncodingの値を確認することができます

new System.IO.StreamReader("path", true) 

ファイル。ただし、バイトエンコーディングマークが存在しない場合、CurrentEncodingはデフォルトでEncoding.Defaultになります。

Refer codeproject solution to detect encoding

+3

何バイトエンコーディングマークが存在しない場合は、CurrentEncodingはEncoding.UTF8を使用します。 ** not ** Encoding.Default。 "detectEncodingFromByteOrderMarksパラメータは、ストリームの最初の3バイトを調べてエンコーディングを検出します。ファイルが適切なバイト順序マークで始まる場合は、UTF-8、リトルエンディアンのUnicode、およびビッグエンディアンのUnicodeテキストを自動的に認識します。 UTF8Encodingが使用されています。 [ドキュメントから](http://msdn.microsoft.com/en-us/library/9y86s1a9.aspx) – MarkJ

5

あなたは最初のファイルのエンコーディングを確認する必要があります。あなたはエンコーディングが何であるかを知っておく必要があり、この

System.Text.Encoding enc = null; 
System.IO.FileStream file = new System.IO.FileStream(filePath, 
    FileMode.Open, FileAccess.Read, FileShare.Read); 
if (file.CanSeek) 
{ 
    byte[] bom = new byte[4]; // Get the byte-order mark, if there is one 
    file.Read(bom, 0, 4); 
    if ((bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) || // utf-8 
     (bom[0] == 0xff && bom[1] == 0xfe) || // ucs-2le, ucs-4le, and ucs-16le 
     (bom[0] == 0xfe && bom[1] == 0xff) || // utf-16 and ucs-2 
     (bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff)) // ucs-4 
    { 
     enc = System.Text.Encoding.Unicode; 
    } 
    else 
    { 
     enc = System.Text.Encoding.ASCII; 
    } 

    // Now reposition the file cursor back to the start of the file 
    file.Seek(0, System.IO.SeekOrigin.Begin); 
} 
else 
{ 
    // The file cannot be randomly accessed, so you need to decide what to set the default to 
    // based on the data provided. If you're expecting data from a lot of older applications, 
    // default your encoding to Encoding.ASCII. If you're expecting data from a lot of newer 
    // applications, default your encoding to Encoding.Unicode. Also, since binary files are 
    // single byte-based, so you will want to use Encoding.ASCII, even though you'll probably 
    // never need to use the encoding then since the Encoding classes are really meant to get 
    // strings from the byte array that is the file. 

    enc = System.Text.Encoding.ASCII; 
} 
+0

ありがとう! FileStreamはこのコードの後に​​開いており、このコードがいくつかの 'GetEncoding'メソッドで使用されている場合は閉じなければならないことに注意してください。 – Tieme