Frage

Ich versuche, die Zeichencodierung zu erkennen, in meiner Datei verwendet wird.

Ich versuche, mit diesem Code die Standard-Codierung zu bekommen

public static Encoding GetFileEncoding(string srcFile)
    {
      // *** Use Default of Encoding.Default (Ansi CodePage)
      Encoding enc = Encoding.Default;

      // *** Detect byte order mark if any - otherwise assume default
      byte[] buffer = new byte[5];
      FileStream file = new FileStream(srcFile, FileMode.Open);
      file.Read(buffer, 0, 5);
      file.Close();

      if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
        enc = Encoding.UTF8;
      else if (buffer[0] == 0xfe && buffer[1] == 0xff)
        enc = Encoding.Unicode;
      else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
        enc = Encoding.UTF32;
      else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
        enc = Encoding.UTF7;
      else if (buffer[0] == 0xFE && buffer[1] == 0xFF)      
        // 1201 unicodeFFFE Unicode (Big-Endian)
        enc = Encoding.GetEncoding(1201);      
      else if (buffer[0] == 0xFF && buffer[1] == 0xFE)      
        // 1200 utf-16 Unicode
        enc = Encoding.GetEncoding(1200);


      return enc;
    }

My fünf ersten Bytes sind 60, 118, 56, 46 und 49.

Gibt es ein Diagramm, das zeigt, welche Codierung die fünf ersten Bytes entspricht?

War es hilfreich?

Lösung

Sie können nicht auf die Datei hängt eine Stückliste mit. UTF-8 ist es nicht erforderlich. Und Nicht-Unicode-Codierung hat nicht einmal eine Stückliste. Es gibt jedoch auch andere Möglichkeiten, um die Codierung zu erkennen.

UTF-32

BOM ist 00 00 FE FF (für BE) oder FF FE 00 00 (für LE).

Aber UTF-32 ist einfach auch ohne BOM zu erkennen. Dies ist, weil der Unicode-Codepunktbereich zu U + 10FFFF beschränkt ist, und somit UTF-32-Einheiten haben immer das Muster 00 {00-10} xx xx (für BE) oder xx xx {00-10} 00 (LE) . Wenn die Daten, die eine Länge aufweist, die ein Vielfaches von 4 ist, und folgt einem dieser Muster können Sie sicher es ist UTF-32 übernehmen. Falsch positive Ergebnisse sind fast unmöglich, aufgrund der Seltenheit von 00 Bytes in byteorientierte Kodierungen.

US-ASCII

No BOM, aber Sie brauchen nicht ein. ASCII kann leicht durch den Mangel an Bytes in dem 80-FF Bereich identifiziert werden.

UTF-8

BOM ist EF BB BF. Aber man kann sich darauf nicht verlassen. Viele UTF-8-Dateien keine BOM haben, besonders wenn sie auf Nicht-Windows-Systemen stammen.

Aber Sie können sicher davon ausgehen, dass, wenn eine Datei validates als UTF-8, es ist UTF-8. Falsch positive Ergebnisse sind selten.

Insbesondere gegeben, dass die Daten nicht ASCII sind, die falsch-positive Rate für eine 2-Byte-Sequenz ist nur 3,9% (1920/49152). Bei einer 7-Byte-Sequenz, ist es weniger als 1%. Für eine 12-Byte-Sequenz, ist es weniger als 0,1%. Für eine 24-Byte-Sequenz, es ist weniger als 1 zu einer Million.

UTF-16

BOM ist FE FF (für BE) oder FF FE (für LE). Beachten Sie, dass der UTF-16 LE BOM wird zu Beginn des UTF-32LE BOM gefunden, so Check UTF-32 zuerst.

Wenn Sie zufällig eine Datei haben, die hauptsächlich aus ISO-8859-1 Zeichen besteht, mit der Hälfte des Bytes einer Datei sein 00 wäre auch ein starker Indikator für UTF-16 sein.

Ansonsten ist die einzige zuverlässige Methode UTF-16 ohne BOM zu erkennen, ist für Ersatzpaare suchen (D [8-B] xx D [CF] xx), aber nicht-BMP-Zeichen werden zu selten verwendet zu machen dieser Ansatz praktisch.

XML

Wenn Sie Ihre Datei beginnt mit dem Bytes 3C 3F 78 6D 6C (das heißt, die ASCII-Zeichen "encoding= Erklärung. Wenn vorhanden, dann wird diese Codierung verwenden. Wenn nicht vorhanden, dann übernimmt UTF-8, die die Standard-XML-Kodierung ist.

Wenn Sie EBCDIC unterstützen müssen, sehen auch für die äquivalente Sequenz 4C 6F A7 94 93.

Im Allgemeinen, wenn Sie ein Dateiformat haben, das eine Kodierungsdeklaration enthält, dann suchen Sie nach dieser Erklärung anstatt zu versuchen, die Codierung zu erraten.

Keine der oben

Es gibt Hunderte von anderen Kodierungen, die mehr Aufwand erfordern zu erfassen. Ich empfehle versuchen, Mozillas charset Detektor oder ein .NET-Port davon .

Eine vernünftige default

Wenn Sie die UTF-Codierungen ausgeschlossen haben, und haben keine Codierungsdeklaration oder statistische Erfassung, dass Punkte auf einer anderen Kodierung, übernehmen ISO-8859-1 oder die eng verwandte Windows 1252 . (Beachten Sie, dass der neueste HTML-Standard erfordert eine „ISO-8859-1“ Deklaration interpretiert als Windows 1252 werden.) Standard-Codepage Being Windows für Englisch (und andere populäre Sprachen wie Spanisch, Portugiesisch , Deutsch und Französisch), es ist die am häufigsten anzutreff kodieren andere als UTF-8.

Andere Tipps

Wenn Sie eine „einfache“ Lösung verfolgen möchten, können Sie diese Klasse finde ich zusammen nützlich setzen:

http://www.architectshack.com/TextFileEncodingDetector.ashx

Es hat die BOM Erkennung automatisch zuerst, und dann versucht, zwischen Unicode-Codierungen ohne BOM, vs einer anderen Standard-Kodierung (in der Regel von Windows-1252, falsch beschriftet als Encoding.ASCII in .NET).

zu unterscheiden

Wie oben erwähnt, eine „schwere“ Lösung NCharDet oder MLang beteiligt ist, kann besser geeignet sein, und als ich auf der Übersichtsseite dieser Klasse beachten Sie, ist das Beste mit dem Benutzer irgendeine Form von Interaktivität zu schaffen, wenn überhaupt möglich, weil es einfach keine 100% Erkennungsrate möglich!

Mit StreamReader und leiten sie die Codierung für Sie zu erkennen:

using (var reader = new System.IO.StreamReader(path, true))
{
    var currentEncoding = reader.CurrentEncoding;
}

Und Verwendung Code-Seite Identifiers https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756 (v = VS.85) aspx um Schaltlogik abhängig von ihm.

Mehrere Antworten sind hier aber niemand hat usefull Code geschrieben.

Hier ist mein Code, der alle Codierungen feststellt, dass Microsoft in Framework 4 in der Klasse Stream erkennt.

Natürlich müssen Sie diese Funktion aufrufen, sofort nachdem die Liste zu öffnen, bevor irgendetwas anderes aus dem Stream zu lesen, weil die BOM die ersten Bytes im Strom sind.

Diese Funktion erfordert einen Stream, der (zum Beispiel ein Filestream) suchen können. Wenn Sie einen Stream, die nicht suchen können Sie einen komplizierteren Code schreiben muss, dass die Renditen ein Byte-Puffer mit den Bytes, die bereits gelesen wurden, aber das sind nicht BOM.

/// <summary>
/// UTF8    : EF BB BF
/// UTF16 BE: FE FF
/// UTF16 LE: FF FE
/// UTF32 BE: 00 00 FE FF
/// UTF32 LE: FF FE 00 00
/// </summary>
public static Encoding DetectEncoding(Stream i_Stream)
{
    if (!i_Stream.CanSeek || !i_Stream.CanRead)
        throw new Exception("DetectEncoding() requires a seekable and readable Stream");

    // Try to read 4 bytes. If the stream is shorter, less bytes will be read.
    Byte[] u8_Buf = new Byte[4];
    int s32_Count = i_Stream.Read(u8_Buf, 0, 4);
    if (s32_Count >= 2)
    {
        if (u8_Buf[0] == 0xFE && u8_Buf[1] == 0xFF)
        {
            i_Stream.Position = 2;
            return new UnicodeEncoding(true, true);
        }

        if (u8_Buf[0] == 0xFF && u8_Buf[1] == 0xFE)
        {
            if (s32_Count >= 4 && u8_Buf[2] == 0 && u8_Buf[3] == 0)
            {
                i_Stream.Position = 4;
                return new UTF32Encoding(false, true);
            }
            else
            {
                i_Stream.Position = 2;
                return new UnicodeEncoding(false, true);
            }
        }

        if (s32_Count >= 3 && u8_Buf[0] == 0xEF && u8_Buf[1] == 0xBB && u8_Buf[2] == 0xBF)
        {
            i_Stream.Position = 3;
            return Encoding.UTF8;
        }

        if (s32_Count >= 4 && u8_Buf[0] == 0 && u8_Buf[1] == 0 && u8_Buf[2] == 0xFE && u8_Buf[3] == 0xFF)
        {
            i_Stream.Position = 4;
            return new UTF32Encoding(true, true);
        }
    }

    i_Stream.Position = 0;
    return Encoding.Default;
}

Wenn Sie Ihre Datei beginnt mit dem 60 Bytes, 118, 56, 46 und 49, dann haben Sie einen mehrdeutigen Fall. Es könnte UTF-8 (ohne BOM) oder einer der Single-Byte-Codierungen wie ASCII, ANSI, ISO-8859-1 usw. sein.

Ich benutze Ude , die eine C # Port von Mozilla Universal-Charset Detector ist. Es ist einfach zu bedienen und gibt einige wirklich gute Ergebnisse.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top