2012-05-25 15 views
6

Im ReadAllTextdosya kodlama bilinmeyen

ile
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++; 
    } 

bir dosyayı okurken ben bazı dosyaları okumak çalışırsanız ReadAllText nasıl kullanılır I (... ÖÜÄÀ için) yanlış karakter geri bazen olsun. Çıktı gibidir, onun kodlama ile bazı sorun olduğundan '?':

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

bir çözüm ReadAllText içinde kodlamasını ayarlamak için olurdu, sorunu çözmek olabilir ReadAllText(@"c:\\c\\file.txt", Encoding.UTF8) gibi bir şey diyelim. Ama ya ben hala alırsam? çıktı olarak? Dosyanın kodlamasını bilmiyorsam ne olur? Ve her bir dosya farklı bir kodlamaya sahipse ne olur? C# ile yapmanın en iyi yolu ne olurdu? Teşekkür ederiz

+1

Kodlamanın ne olduğunu bilmeniz gerekir. Ve sadece dosyanın içeriğine dayalı olarak bulmak için% 100 güvenilir bir yol yoktur. –

+0

Bu yayına bakınız http://stackoverflow.com/questions/2239968/c-sharp-file-readalltext-doing-weird-things – Dhaval

cevap

6

Güvenilir bir şekilde bunu yapmanın tek yolu, metin dosyasının başında byte order marks'u aramaktır. (Bu blob daha genel olarak kullanılan karakter kodlamanın endianitesini temsil eder, aynı zamanda şifrelemeyi de içerir - örneğin UTF8, UTF16, UTF32). Ne yazık ki, bu yöntem sadece Unicode tabanlı kodlamalar için çalışır ve bundan önce hiçbir şey (hangi daha az güvenilir yöntemler kullanılmalıdır).

StreamReader tipi kodlamasını belirlemek için bu işaretleri tespit destekler - basitçe gibi parametreye bir bayrak geçmesi gerekiyor: O zamana kadar kullanılan kodlamayı belirlemek için stremReader.CurrentEncoding değerini kontrol edebilirsiniz

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

dosya. Bununla birlikte, hiçbir bayt kodlama işareti yoksa, CurrentEncoding'un Encoding.Default için varsayılan olacağını unutmayın.

Refer codeproject solution to detect encoding

+3

hiçbir bayt kodlama işaretleri varsa, o zaman CurrentEncoding Encoding.UTF8 kullanacak ** değil ** Encoding.Default. "DetectEncodingFromByteOrderMarks parametresi, akışın ilk üç baytına bakarak kodlamayı algılar. Dosya uygun bayt sırası işaretleriyle başlarsa, UTF-8, küçük endian Unicode ve big-endian Unicode metnini otomatik olarak tanır. UTF8Encoding kullanılır. " [docs] (http://msdn.microsoft.com/en-us/library/9y86s1a9.aspx) – MarkJ

5

Önce dosya kodlamasını kontrol etmeliyiz. deneyin bu

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

Teşekkürler! FileStream'in bu koddan sonra açık olduğunu ve bu kodun bazı GetEncoding' yönteminde kullanılması durumunda kapatılması gerektiğini unutmayın. – Tieme