J'essaie de détecter quel encodage de caractères est utilisé dans mon fichier.
J'essaie avec ce code pour obtenir le codage standard
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;
}
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 n'en a pas besoin. Et les encodages non-Unicode n'ont même pas de nomenclature. Il existe cependant d'autres moyens de détecter le codage.
La nomenclature est 00 FEC (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 modèle 00 {00-10} xx xx (pour BE) ou xx xx {00-10} 00 (pour LE). . Si les données ont une longueur multiple de 4 et suivent l'un de ces modèles, vous pouvez sans risque supposer qu'il s'agit du format UTF-32. Les faux positifs sont presque impossibles en raison de la rareté de 00 octets dans les codages orientés octets.
Pas de nomenclature, mais vous n'en avez pas besoin. ASCII peut être facilement identifié par le manque d'octets dans la plage de 80-FF.
La nomenclature correspond à 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 autres que Windows.
Mais vous pouvez sans risque supposer que, si un fichier est validé en tant que UTF-8, il est UTF-8. Les faux positifs sont rares.
Plus précisément, étant donné que les données ne sont pas ASCII, le taux de faux positifs pour une séquence de 2 octets n'est que 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 de 1 sur un million.
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 d'abord UTF-32.
Si vous avez un fichier composé principalement de caractères ISO-8859-1, le fait que la moitié de ses octets soient égale à 00 sera également un indicateur fort de la norme UTF-16.
Sinon, 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. .
Si votre fichier commence par les octets 3C 3F 78 6D 6C (c’est-à-dire les caractères ASCII "" <? Xml "), recherchez une déclaration encoding=
. Si présent, utilisez cet encodage. S'il est absent, 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 cette déclaration plutôt que d'essayer de deviner le codage.
Il existe des centaines d'autres encodages, qui nécessitent davantage d'efforts de détection. Je recommande d'essayer détecteur de charset de Mozilla ou n portage .NET .
Si vous avez exclu les codages UTF et que vous n'avez pas de déclaration de codage ou de détection statistique pointant vers un codage différent, supposons que ISO-8859-1 ou le proche parent Windows -1252 . (Notez que la dernière norme HTML requiert une déclaration "ISO-8859-1" pour être interprétée comme Windows-1252.) Page de code par défaut de Windows pour l'anglais (et d'autres langues populaires telles que l'espagnol, le portugais, l'allemand et le français), il s'agit du codage le plus couramment rencontré, à l'exception de l'UTF-8.
Si vous souhaitez rechercher une solution "simple", vous trouverez peut-être utile ce cours:
http://www.architectshack.com/TextFileEncodingDetector.ashx
La détection de nomenclature est automatiquement effectuée en premier, puis tente de différencier les codages Unicode sans nomenclature par rapport à un autre codage par défaut (généralement Windows-1252, incorrectement étiqueté Encoding.ASCII dans .Net).
Comme indiqué ci-dessus, une solution "plus lourde" impliquant NCharDet ou MLang peut être plus appropriée, et comme je l'indique sur la page de présentation de cette classe, le mieux est de fournir une forme ou une autre d'interactivité avec l'utilisateur, car Il n'y a pas de taux de détection de 100% possible!
Utilisez StreamReader
et dirigez-le pour détecter le codage 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 celle-ci.
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.
Vous devez évidemment appeler cette fonction immédiatement après l'ouverture du flux avant de lire quoi que ce soit d'autre dans le flux, car les nomenclatures sont les premiers octets du flux.
Cette fonction nécessite un flux pouvant rechercher (par exemple un FileStream). Si vous avez un flux qui ne peut pas chercher, vous devez écrire un code plus compliqué renvoyant un tampon d'octets avec les octets déjà lus mais qui ne sont pas des nomenclatures.
/// <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;
}
Oui, il y en a un ici: http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding .
Vous devriez lire ceci: Comment puis-je détecter l'encodage/la page de code d'un fichier texte
J'utilise de c'est un port C # de Mozilla Universal Charset Detector. Il est facile à utiliser et donne de très bons résultats.
Si votre fichier commence par les octets 60, 118, 56, 46 et 49, vous avez un cas ambigu. Il peut s'agir de UTF-8 (sans nomenclature) ou de l'un des codages à un octet tels qu'ASCII, ANSI, ISO-8859-1, etc.