Comment détecter l’encodage de caractères d’un fichier texte?

J’essaie de détecter quel encodage de caractères est utilisé dans mon fichier.

J’essaie avec ce code pour obtenir l’encodage standard

public static Encoding GetFileEncoding(ssortingng 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; } 

Mes cinq premiers octets sont 60, 118, 56, 46 et 49.

Existe-t-il un graphique indiquant quel codage correspond à ces cinq premiers octets?

Vous ne pouvez pas compter sur le fichier ayant une nomenclature. UTF-8 ne l’exige pas. Et les encodages non-Unicode n’ont même pas de nomenclature. Il existe toutefois d’autres moyens de détecter le codage.

UTF-32

La nomenclature est 00 00 FE FF (pour BE) ou FF FE 00 00 (pour LE).

Mais UTF-32 est facile à détecter même sans nomenclature. En effet, la plage de points de code Unicode est limitée à U + 10FFFF et les unités UTF-32 ont donc toujours le motif 00 {0x | 10} xx xx (pour BE) ou xx xx {0x | 10} 00 (pour LE) . Si les données ont une longueur qui est un multiple de 4, et suit l’un de ces modèles, vous pouvez supposer que c’est UTF-32. Les faux positifs sont presque impossibles en raison de la rareté de 00 octets dans les codages orientés octets.

US-ASCII

Pas de nomenclature, mais vous n’en avez pas besoin. L’ASCII peut être facilement identifié par le manque d’octets dans la plage 80-FF.

UTF-8

La nomenclature est EF BB BF. Mais vous ne pouvez pas compter sur cela. De nombreux fichiers UTF-8 ne possèdent pas de nomenclature, en particulier s’ils proviennent de systèmes non Windows.

Mais vous pouvez supposer que si un fichier est validé en UTF-8, il s’agit de UTF-8. Les faux positifs sont rares.

Spécifiquement, étant donné que les données ne sont pas ASCII, le taux de faux positifs pour une séquence de 2 octets est seulement de 3,9% (1920/49152). Pour une séquence de 7 octets, c’est moins de 1%. Pour une séquence de 12 octets, c’est moins de 0,1%. Pour une séquence de 24 octets, c’est moins d’une sur un million.

UTF-16

La nomenclature est FE FF (pour BE) ou FF FE (pour LE). Notez que la nomenclature UTF-16LE se trouve au début de la nomenclature UTF-32LE, vérifiez donc UTF-32 en premier.

Il peut y avoir des fichiers UTF-16 sans nomenclature, mais il serait très difficile de les détecter. Le seul moyen fiable de reconnaître UTF-16 sans nomenclature est de rechercher des paires de substitution (D [8-B] xx D [CF] xx), mais les caractères non BMP sont trop rarement utilisés pour rendre cette approche pratique.

XML

Si votre fichier commence par les octets 3C 3F 78 6D 6C (c.-à-d. Les caractères ASCII “encoding= . Si présent, utilisez cet encodage. S’il est absent, alors supposons UTF-8, qui est le codage XML par défaut.

Si vous devez prendre en charge EBCDIC, recherchez également la séquence équivalente 4C 6F A7 94 93.

En général, si vous avez un format de fichier contenant une déclaration de codage, recherchez-la plutôt que d’essayer de deviner l’encodage.

Aucune de ces réponses

Il existe des centaines d’autres encodages, qui nécessitent plus d’efforts pour être détectés. Je recommande d’essayer le détecteur de charset de Mozilla ou un port .NET de celui-ci .

Si vous souhaitez poursuivre une solution “simple”, vous pourriez trouver cette classe utile:

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

Il effectue d’abord la détection de nomenclature, puis essaie de différencier les encodages Unicode sans nomenclature des autres codages par défaut (généralement Windows-1252, incorrectement étiqueté Encoding.ASCII dans .Net).

Comme noté ci-dessus, une solution “plus lourde” impliquant NCharDet ou MLang peut être plus appropriée, et comme je le note sur la page d’aperçu de cette classe, le mieux est de fournir une certaine forme d’interactivité avec l’utilisateur. le taux de détection de 100% n’est pas possible!

Utilisez StreamReader et dirigez-le pour détecter l’encodage pour vous:

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

Et utilisez les identificateurs de page de code https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx afin de changer de logique en fonction de cela.

Plusieurs réponses sont ici mais personne n’a posté de code utile.

Voici mon code qui détecte tous les encodages que Microsoft détecte dans Framework 4 dans la classe StreamReader.

Évidemment, vous devez appeler cette fonction immédiatement après avoir ouvert le stream avant de lire autre chose dans le stream car la nomenclature est le premier octet du stream.

Cette fonction nécessite un Stream pouvant rechercher (par exemple un FileStream). Si vous avez un Stream qui ne peut pas être recherché, vous devez écrire un code plus compliqué qui renvoie un tampon d’octets avec les octets qui ont déjà été lus mais qui ne sont pas des BOM.

 ///  /// UTF8 : EF BB BF /// UTF16 BE: FE FF /// UTF16 LE: FF FE /// UTF32 BE: 00 00 FE FF /// UTF32 LE: FF FE 00 00 ///  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; } 

Vous devriez lire ceci: Comment puis-je détecter l’encodage / page de codes d’un fichier texte?

Si votre fichier commence par les octets 60, 118, 56, 46 et 49, vous avez un cas ambigu. Il peut s’agir d’un UTF-8 (sans BOM) ou de l’un des codages à un seul octet tels que ASCII, ANSI, ISO-8859-1, etc.

J’utilise Ude qui est un port C # de Mozilla Universal Charset Detector. Il est facile à utiliser et donne de très bons résultats.