2010-10-04 14 views
3

Je viens de tomber sur another question dans lequel quelqu'un a suggéré d'utiliser new ASCIIEncoding().GetBytes(someString) pour convertir d'une chaîne en octets. Pour moi, il était évident que cela ne devrait pas fonctionner pour les caractères non-ASCII. Mais comme il s'avère, ASCIIEncoding remplace heureusement les caractères invalides avec '?'. Je suis très confus à ce sujet parce que ce genre de casse la règle de la moindre surprise. En Python, ce serait u"some unicode string".encode("ascii") et la conversion est stricte par défaut de sorte que les caractères non-ASCII conduiraient à une exception dans cet exemple.Chaîne stricte à l'encodage d'octets en C#

Deux questions:

  1. Comment les chaînes strictement converties en un autre encodage (comme ASCII ou Windows 1252), de sorte qu'une exception est levée si des caractères non valides se produisent? En passant, je ne veux pas une boucle foreach convertissant chaque nombre Unicode en octet, puis en vérifiant le huitième bit. Ceci est supposé être fait par un grand framework comme .NET (ou Python ^^).
  2. Des idées sur la logique de ce comportement par défaut? Pour moi, il est plus logique de faire des conversions strictes par défaut ou au moins de définir un paramètre à cet effet (Python autorise "replace", "ignore", "strict").

Répondre

7

.Net offre la possibilité de lancer une exception si la conversion de codage échoue. Vous devrez utiliser la classe EncoderExceptionFallback (lève une exception EncoderFallbackException si un caractère d'entrée ne peut pas être converti en une séquence d'octets de sortie codée) pour créer un codage. Le code suivant est de la documentation de cette classe:

Encoding ae = Encoding.GetEncoding(
       "us-ascii", 
       new EncoderExceptionFallback(), 
       new DecoderExceptionFallback()); 

ensuite utiliser ce codage pour effectuer la conversion:

// The input string consists of the Unicode characters LEFT POINTING 
// DOUBLE ANGLE QUOTATION MARK (U+00AB), 'X' (U+0058), and RIGHT POINTING 
// DOUBLE ANGLE QUOTATION MARK (U+00BB). 
// The encoding can only encode characters in the US-ASCII range of U+0000 
// through U+007F. Consequently, the characters bracketing the 'X' character 
// cause an exception. 

string inputString = "\u00abX\u00bb"; 
byte[] encodedBytes = new byte[ae.GetMaxByteCount(inputString.Length)]; 
int numberOfEncodedBytes = 0; 
try 
{ 
    numberOfEncodedBytes = ae.GetBytes(inputString, 0, inputString.Length, 
             encodedBytes, 0); 
} 
catch (EncoderFallbackException e) 
{ 
    Console.WriteLine("bad conversion"); 
} 

Ce MSDN page, "Character Encoding in the .NET Framework" discute, dans une certaine mesure, la raison d'être le comportement de conversion par défaut. En résumé, ils ne souhaitaient pas perturber les applications héritées qui dépendent de ce comportement. Ils recommandent cependant de remplacer la valeur par défaut.

+0

Bonne explication. J'avais vu la phrase "Vous pourriez envisager d'avoir votre application définir EncoderFallback ou DecoderFallback à EncoderExceptionFallback ou DecoderExceptionFallback pour empêcher les séquences avec le 8ème ensemble de bits." dans la documentation mais il n'était pas évident pour moi qu'il puisse être utilisé pour des conversions strictes. – AndiDog