Bonjour,
je suis en train de faire un programme qui doit vérifier que l'encodage des caractères est en utf-8.
Vérifier le BOM ne suffit pas, et je souhaiterai valider le fichier caractère par caractère avez vous une méthode ?
Version imprimable
Bonjour,
je suis en train de faire un programme qui doit vérifier que l'encodage des caractères est en utf-8.
Vérifier le BOM ne suffit pas, et je souhaiterai valider le fichier caractère par caractère avez vous une méthode ?
C'est pas très évident, tu peux pas le faire en utilisant directement l'objet Encoding, il faut passer par le Decoder et sa propriété Fallback. J'ai fait une petite méthode d'extension qui permet de tester si le contenu est correct :
Pour l'utiliser tu peux faire ça :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public static class Extensions { public static bool TryGetString(this Encoding encoding, byte[] bytes, out string result) { return encoding.TryGetString(bytes, 0, bytes.Length, out result); } public static bool TryGetString(this Encoding encoding, byte[] bytes, int index, int count, out string result) { result = null; var decoder = encoding.GetDecoder(); decoder.Fallback = DecoderFallback.ExceptionFallback; try { int charCount = decoder.GetCharCount(bytes, index, count); char[] chars = new char[charCount]; decoder.GetChars(bytes, index, count, chars, 0); result = new string(chars); return true; } catch(DecoderFallbackException) { return false; } } }
Soit dit en passant, c'est pas génial de devoir catcher l'exception... idéalement il faudrait implémenter un DecoderFallback personnalisé, mais j'ai pas encore trouvé comment faireCode:
1
2
3
4
5
6
7
8
9
10 byte[] bytes = File.ReadAllBytes(fileName); string text; if (Encoding.UTF8.TryGetString(bytes, out text)) { Console.WriteLine("L'encodage UTF8 du fichier est correct"); } else { Console.WriteLine("L'encodage UTF8 du fichier est incorrect"); }
Merci cela m'aide beaucoup.:ccool:
@Tomlev :
Ca gère BOM/pas BOM ?
D'après mes tests oui (passage du fichier en utf-8 bom et utf-8 depuis notepad++).
Bonjour,
comment peut-on faire lorsque l'on lit un fichier ligne par ligne et utiliser la solution donnée en exemple car j'utilise de gros fichier et lorsque j'utilise readallbyte c'est très lourd.
Y-a-t-il un moyen de lire le fichier ligne par ligne et boucler ?
Merci.
Tu peux faire ça :
Le 2e paramètre du constructeur de UTF8Encoding s'appelle throwOnInvalidBytes, donc si tu le mets à true ça lève une exception quand un caractère illisible est rencontré.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 var encoding = new UTF8Encoding(true, true); using (var reader = new StreamReader(fileName, encoding)) { try { while (reader.ReadLine() != null) { ... } } catch(DecoderFallbackException) { // Oups, caractères non valides... } }
Ok, ça marche.
Maintenant j'aurai besoin de lire chaque élément pour avoir la liste des caractères qui ne sont pas en UTF-8.
Car lorsque j'utilise l'exception décoderfallback je n'ai l'erreur que pour le premier élément incorrect du flux passé.
Est ce possible de lire le fichier caractère par caractère et de lever l'exception décoder fallback afin de savoir où se trouve le problème dans le fichier ?
Merci.
Là ça se complique sérieusement... Tu pourrais essayer de créer un DecoderFallback spécifique qui garde dans une liste les caractères invalides détectés et leur position, mais j'ai commencé à essayer et c'est pas évident (en tous cas j'ai pas réussi à faire un truc qui marche bien)