Déterminer une chaîne de codage en C#
Est-il possible de déterminer une chaîne de codage en C#?
Dire, j'ai un nom de fichier de la chaîne, mais je ne sais pas si c'est codé en Unicode UTF-16 ou le système de codage par défaut, comment puis-je savoir?
- Vous ne pouvez pas "coder" en Unicode. Et il n'y a aucun moyen de déterminer automatiquement l'encodage d'une Chaîne de caractères, sans aucune autre information préalable.
- "Vous ne pouvez pas "coder' en Unicode" - si l'on interprète Unicode UTF-16 (ou tout autre UTF*), alors que c'est un bon moyen de l'écriture de code-points comme une séquence d'octets (=encodage).
- comment pouvez-vous écrire de telles approximations? UTF-16 est l'un des moyens possibles pour coder des données Unicode. Vous ne pouvez pas "Unicode-encoder"; Unicode n'est pas de l'UTF-; et UTF - n'est pas Unicode. Désolé, mais si nous continuer à écrire de telles approximations, comment Unicode liées à des comportements de changer? Les débutants pourront toujours se confondre par la sombre Unicode monstre et les choses ne changeront jamais. Soyons précis.
- pour être plus clair peut-être: de l'encodage Unicode code-points dans les chaînes d'octets d'un jeu de caractères à l'aide d'un "codage" scheme (utf-, iso-, big5, shift-jis, etc...), et vous décoder les chaînes d'octets à partir d'un jeu de caractères Unicode. Vous n'avez pas coder bytestrings en Unicode. Vous n'avez pas de décoder l'Unicode dans bytestrings.
- Grâce NicDumZ, vous avez juste fait me sentir vraiment stupide. :S
- le codage lui-même (en particulier UTF-16) est aussi communément appelé "Unicode". Bon ou mauvais, c'est la vie. Même dans .NET, regarder l'Encodage.Unicode - sens de l'UTF-16.
- eh bien, je ne le savais pas .NET est donc trompeuse. Qui ressemble à une terrible habitude d'apprendre. Et désolé @krebstar, ce n'était pas mon intention (je pense toujours que votre édité question fait beaucoup plus de sens aujourd'hui qu'avant)
- Il existe un moyen de déterminer de manière probabiliste dont l'encodage à utiliser. Regardez ce que fait IE (et maintenant aussi les FF avec Vue - Encodage des Caractères - Auto-détection) pour qui: il tente un encodage et de voir si il est peut-être "bien écrit <de mettre un nom de langue ici>", ou modifier et essaie de nouveau. Allez, comme ça peut être amusant!
- toute solution finale avec l'intégralité du code source de l'échantillon de travail à ce sujet ?
- Cette question n'a pas de sens comme l'a écrit. Dans .Net, une fois que vous avez un objet de type string, ses caractères sont les caractères Unicode dans la plage U+0000 à U+FFFF. Il n'est plus "a un encodage", dans le sens de la question. Ou sinon, vous pourriez dire que .Net de la chaîne de l'encodage est UTF-16. Tout "codage" est traité par n'importe quel code converti à l'origine bytestream dans le .Net objet de type string.
Vous devez vous connecter pour publier un commentaire.
Découvrez Utf8Checker il est simple de classe qui fait exactement ce dans le plus pur du code managé.
http://utf8checker.codeplex.com
Avis: comme l'a déjà souligné "déterminer l'encodage" n'a de sens que pour les flux d'octets. Si vous avez une chaîne, il est déjà encodée à partir quelqu'un le long de la voie qui savait déjà à deviner ou à l'encodage pour obtenir la chaîne de caractères dans la première place.
Le code ci-dessous présente les caractéristiques suivantes:
Comme d'autres l'ont dit, aucune solution ne peut être parfait (et certainement on ne peut pas différencier entre les différents 8 bits ASCII étendu codages utilisés dans le monde entier), mais nous pouvons obtenir "assez bien", surtout si le développeur également présente à l'utilisateur une liste d'autres encodages comme indiqué ici: Qu'est-ce que l'encodage le plus courant de chaque langue?
Une liste complète des Codages peuvent être trouvés en utilisant
Encoding.GetEncodings();
Il dépend de l'endroit où la chaîne de caractères "provient". Un .NET de chaîne Unicode (UTF-16). La seule façon dont il pourrait être différente si vous, dire, lire les données à partir d'une base de données dans un tableau d'octets.
Ce CodeProject article pourrait vous intéresser: Détecter l'Encodage pour et texte sortants
Jon Skeet est Chaînes de caractères en C# et .NET est une excellente explication de .NET chaînes.
Je sais c'est un peu tardive mais pour être clair:
Une chaîne n'a pas vraiment de codage... dans .NET le une chaîne de caractères est une collection de char objets. Essentiellement, si c'est une chaîne, il a déjà été décodé.
Cependant, si vous lisez le contenu d'un fichier, qui est faite d'octets, et souhaitez convertir une chaîne de caractères, puis l'encodage du fichier doit être utilisé.
.NET comprend l'encodage et le décodage des classes de: ASCII, UTF7, UTF8, UTF32 et plus.
La plupart de ces codages contenir certaines d'ordre d'octet marques qui peuvent être utilisés pour distinguer le type de codage a été utilisé.
L' .NET de Système de classe.IO.StreamReader est en mesure de déterminer l'encodage utilisé dans un flux, par la lecture de ces l'ordre des octets des marques;
Voici un exemple:
Encoding.Default
comme un StreamReader paramètre, mais alors le code ne sera pas en mesure de détecter UTF8 sans BOM.Une autre option, très tardivement, désolé:
http://www.architectshack.com/TextFileEncodingDetector.ashx
Ce petit C#-seulement la classe utilise les NOMENCLATURES s'il est présent, essaie de détecter automatiquement possible encodages unicode autrement, et tombe en arrière si aucun des encodages Unicode est possible ou probable.
Il sonne comme UTF8Checker référencé ci-dessus ne fait quelque chose de similaire, mais je pense que c'est légèrement plus large dans son champ d'application - au lieu de simplement en UTF8, il vérifie également pour les autres encodages Unicode (UTF-16 LE ou ÊTRE) qui pourrait être absent une NOMENCLATURE.
Espère que cela aide quelqu'un!
La SimpleHelpers.FileEncoding package Nuget enroule une C# port de Mozilla jeu de caractères Universel Détecteur de dans un cul-de-API simple:
Ma solution est d'utiliser intégré dans le fourre avec certaines réserves.
J'ai choisi la stratégie d'une réponse à une autre question sur stackoverflow mais je ne peux pas le trouver maintenant.
Il vérifie la NOMENCLATURE d'abord à l'aide de la logique intégrée dans StreamReader, si il y a de la NOMENCLATURE, l'encodage sera autre chose que
Encoding.Default
, et nous devons faire confiance à ce résultat.Si non, il vérifie si les octets de la séquence UTF-8 valide séquence. si elle l'est, elle suppose que l'UTF-8 comme encodage, et si non, encore une fois, la valeur par défaut codage ASCII sera le résultat.
Remarque: ce fut une expérience pour voir comment le codage UTF-8 a travaillé à l'interne. La solution proposée par vilicvane, l'utilisation d'un
UTF8Encoding
objet est initialisé à lever une exception sur le décodage de l'échec, est beaucoup plus simple, et se fait de la même chose.J'ai écrit ce morceau de code pour différencier entre UTF-8 et Windows-1252. Il ne devrait pas être utilisé pour de gigantesques fichiers texte, mais, depuis qu'il charge la totalité de la chose dans la mémoire et analyses complètement. Je l'ai utilisé pour .srt sous-titres des fichiers, juste pour être en mesure de les enregistrer en arrière dans l'encodage dans lequel ils ont été chargés.
L'encodage donné à la fonction comme ref devrait être la 8-bits de secours de l'encodage à utiliser dans le cas où le fichier est détecté comme n'étant pas valide UTF-8; en général, sur les systèmes Windows, ce sera Windows-1252. Ce n'est pas faire quelque chose de compliqué, comme la vérification valide ascii gammes de bien, et ne détecte pas l'UTF-16, même sur la marque d'ordre d'octet.
La théorie derrière la bit-à-bit de détection peuvent être trouvés ici:
https://ianthehenry.com/2015/1/17/decoding-utf-8/
Fondamentalement, le peu portée du premier octet détermine combien d'après elle font partie de l'UTF-8 de l'entité. Ces octets après elle sont toujours dans les mêmes bits de large.
else
déclaration aprèsif ((current & 0xE0) == 0xC0) { ... } else if ((current & 0xF0) == 0xE0) { ... } else if ((current & 0xF0) == 0xE0) { ... } else if ((current & 0xF8) == 0xF0) { ... }
. Je suppose queelse
cas serait invalide utf8:isUtf8Valid = false;
. Souhaitez-vous?