Domanda

Io cerco di rilevare quale codifica dei caratteri viene utilizzato nel mio file.

Io cerco con questo codice per ottenere la codifica standard di

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 cinque primo byte sono 60, 118, 56, 46 e 49.

C'è un grafico che mostra quali codifica corrisponde quei cinque primi byte?

È stato utile?

Soluzione

Non si può dipendere dal file con una distinta base. UTF-8 non lo richiede. E codifiche non Unicode non hanno nemmeno una distinta base. Ci sono, tuttavia, altri modi per rilevare la codifica.

UTF-32

BOM è 00 00 FE FF (per BE) o FF FE 00 00 (per LE).

Ma UTF-32 è facile da individuare, anche senza una distinta base. Questo è perché la gamma punto di codice Unicode è limitato a U + 10FFFF, e quindi UTF-32 unità avere sempre il modello 00 {00-10} xx xx (per BE) o xx xx {00-10} 00 (per LE) . Se i dati ha una lunghezza che è un multiplo di 4, e segue uno di questi modelli, si può assumere tranquillamente di UTF-32. I falsi positivi sono quasi impossibile a causa della rarità di 00 byte a byte codifiche-oriented.

US-ASCII

No BOM, ma non hai bisogno di uno. ASCII può essere facilmente identificato dalla mancanza di byte nell'intervallo da 80-FF.

UTF-8

BOM è EF BB BF. Ma non si può fare affidamento su questo. Un sacco di file UTF-8 non hanno una distinta base, soprattutto se hanno avuto origine su sistemi non Windows.

Ma si può tranquillamente supporre che se un file Convalida come UTF-8, è è UTF-8. I falsi positivi sono rari.

In particolare, dato che i dati non sono ASCII, il tasso di falsi positivi per una sequenza a 2 byte è solo il 3,9% (1920/49152). Per una sequenza di 7 byte, è meno di 1%. Per una sequenza di 12 byte, è inferiore allo 0,1%. Per una sequenza di 24 byte, è meno di 1 su un milione.

UTF-16

BOM è FE FF (per BE) o FF FE (per LE). Si noti che il BOM UTF-16 si trova alla partenza della codifica UTF-32LE BOM, in modo da controllare UTF-32 prima.

Se vi capita di avere un file che consiste principalmente di ISO-8859-1, avendo la metà di byte del file sia 00 sarebbe anche un forte indicatore di UTF-16.

In caso contrario, l'unico modo affidabile per riconoscere UTF-16 senza un BOM è quello di cercare le coppie di surrogati (D [8-B] xx D [CF] xx), ma non BMP personaggi sono troppo raramente usato per fare questo approccio pratico.

XML

Se il file inizia con il byte 3C 3F 78 6D 6C (vale a dire, i caratteri ASCII "encoding=. Se presente, quindi utilizzare tale codifica. Se assente, quindi assumere UTF-8, che è la codifica XML predefinito.

Se è necessario supportare EBCDIC, guardate anche per la sequenza equivalente 4C 6F A7 94 93.

In generale, se si dispone di un formato di file che contiene una dichiarazione di codifica, quindi cercare quella dichiarazione piuttosto che cercare di indovinare la codifica.

Nessuno dei precedenti

Ci sono centinaia di altre codifiche, che richiedono uno sforzo maggiore da rilevare. Vi consiglio di provare di Mozilla rilevatore charset o una porta NET ad esso .

Una ragionevole di default

Se hai escluso la codifiche UTF, e non hanno una dichiarazione di codifica o il rilevamento statistico che punta a una codifica diversa, assumono ISO-8859-1 o strettamente correlati Windows 1252 . (Si noti che l'ultimo standard HTML richiede una dichiarazione “ISO-8859-1” devono essere interpretati come di Windows-1252.) Pagina di codice predefinito è Windows' per l'inglese (e altre lingue popolari come spagnolo, portoghese , tedesco e francese), è il più comunemente incontrati codifica diversa da UTF-8.

Altri suggerimenti

Se si vuole perseguire una soluzione "semplice", si potrebbe trovare questa classe ho messo insieme utili:

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

Si fa il rilevamento BOM automaticamente in primo luogo, e poi cerca di distinguere tra codifiche Unicode senza BOM, vs qualche altra codifica predefinita (in genere di Windows-1252, erroneamente etichettato come Encoding.ASCII in Net).

Come indicato sopra, una soluzione "pesante" che coinvolge NCharDet o mlang può essere più appropriato, e come rilevo sulla pagina panoramica di questa classe, la migliore è quello di fornire una qualche forma di interattività con l'utente, se possibile, perché semplicemente non c'è al 100% tasso di rilevamento possibile!

Usa StreamReader e dirigerlo per rilevare la codifica per voi:

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

E l'uso Tabella codici identificativi https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756 (v = vs.85) aspx per logica interruttore seconda esso.

Diverse risposte sono qui, ma nessuno ha pubblicato il codice utile.

Ecco il mio codice che rileva tutte le codifiche che Microsoft rileva nel Framework 4 nella classe StreamReader.

Ovviamente è necessario chiamare subito questa funzione dopo l'apertura del flusso prima di leggere qualsiasi altra cosa dal flusso perché la distinta base sono i primi byte nel flusso.

Questa funzione richiede un flusso che può cercare (ad esempio, un FileStream). Se si dispone di un flusso che non si può chiedere è necessario scrivere un codice più complicato che restituisce un buffer di byte con i byte che sono già stati letti, ma che non sono 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;
}

Se il file inizia con il byte 60, 118, 56, 46 e 49, poi si dispone di un caso ambiguo. Potrebbe essere UTF-8 (senza BOM) o una qualsiasi delle codifiche byte singoli come ASCII, ANSI, ISO-8859-1 ecc.

Ude che è un C # porto di Mozilla Universale Charset Detector. E 'facile da usare e dà alcuni veramente buoni risultati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top