1. Pourquoi les encodages, c'est si compliqué ?
Vous savez déjà que les fichiers texte ne sont qu'une suite d'octets. Et C# (et .NET en général) veut que chaque caractère soit à sa place. À première vue, il suffirait d'indiquer l'encodage lors de la lecture ou de l'écriture — et tout irait bien. Mais dans la vraie vie, ce n'est pas si simple.
Causes de la confusion autour des encodages :
- Héritage historique : les fichiers peuvent être créés sur différents OS et éditeurs, chacun ayant son encodage «par défaut».
- Multiplateforme : un fichier créé sous Windows peut être lu sur Linux ou Mac, où l'encodage par défaut est différent.
- BOM (Byte Order Mark) : un «en-tête» spécial au début du fichier qui existe parfois et parfois non. Il influe sur la façon dont les programmes interprètent le fichier.
2. Qu'est-ce que le BOM et à quoi ça sert
Bref sur le BOM
BOM (Byte Order Mark) est une séquence d'octets spéciale en début de fichier qui dit au programme : «Salut ! Je suis dans tel encodage, et voici comment lire mes octets».
- BOM se rencontre le plus souvent dans les fichiers encodés en UTF-8, UTF-16 et UTF-32.
- Pour UTF-8, le BOM est optionnel. Sa présence ou son absence peut influencer la façon dont différents programmes lisent le fichier.
| Encodage | BOM (vue hexadécimale) | Octets |
|---|---|---|
| UTF-8 | |
|
| UTF-16 LE | |
|
| UTF-16 BE | |
|
| UTF-32 LE | |
|
| UTF-32 BE | |
|
Petit fait du tribunal des encodages : Dans les encodages ASCII et ANSI, le BOM n'est pas utilisé. Mais s'il apparaît, ça surprendra fortement les vieux programmes.
Illustration : où se trouve le BOM
+--------------------------+
| BOM | TEXT BYTES |
+--------------------------+
|EFBBBF| 48 65 6C 6C 6F | // "Hello" en UTF-8 avec BOM
+--------------------------+
EF BB BF — c'est le BOM pour UTF-8. Il se trouve tout au début du fichier.
48 65 6C 6C 6F — ce sont les octets du texte "Hello" en UTF-8 (sans BOM ils seraient identiques).
En résumé : le fichier commence par EF BB BF, puis vient le texte.
3. Mismatch d'encodage : d'où viennent les caractères illisibles
Scénario typique
- Vous écrivez un fichier en UTF-8, mais sans BOM.
- Vous l'ouvrez dans un éditeur sur Windows qui attend Windows-1251 ou UTF-8 avec BOM.
- Résultat — au lieu de "Привет, мир!" vous voyez "Привет, РјРёСЂ!" (caractères illisibles).
Pourquoi ça arrive
- Le programme pense que le fichier est dans une encodage, alors que les octets sont en un autre.
- BOM aide à deviner l'encodage. Mais s'il est absent, la "devinette" se fait à coups d'essais — et ça donne souvent des caractères illisibles.
Exemples de scénarios de mismatch :
- Vous lisez un fichier UTF-8 comme Windows-1251 — tous les caractères non-ASCII deviennent illisibles.
- Vous lisez un fichier UTF-8 avec BOM comme un «pur» UTF-8 — souvent tout va bien, mais certains vieux programmes afficheront les premiers symboles comme des signes incompréhensibles.
- Vous écrivez un fichier avec BOM, alors que l'outil qui doit le lire attend sans — le logiciel externe qui n'aime pas le BOM peut planter.
4. Comment l'encodage et le BOM influent sur les streams
Exemple : écrire et lire un fichier avec différents encodages
// On écrit le fichier en UTF-8 avec BOM
using var writer = new StreamWriter("test_utf8_bom.txt", false, new UTF8Encoding(true));
writer.WriteLine("Bonjour, le monde!");
new UTF8Encoding(true) — active le BOM.
// On écrit le fichier en UTF-8 sans BOM
using var writer = new StreamWriter("test_utf8_no_bom.txt", false, new UTF8Encoding(false));
writer.WriteLine("Bonjour, le monde!");
new UTF8Encoding(false) — sans BOM.
// Lecture du fichier en spécifiant explicitement l'encodage
using var reader = new StreamReader("test_utf8_no_bom.txt", new UTF8Encoding(false));
string line = reader.ReadLine();
Console.WriteLine(line);
Si le fichier est en UTF-8 sans BOM, indiquer explicitement l'encodage garantit une lecture correcte.
Erreur typique
Quand vous n'indiquez pas l'encodage à la lecture, StreamReader essaiera de deviner — il regardera d'abord le BOM, s'il y en a un ; sinon il prendra l'encodage système par défaut (sous Windows c'est souvent Windows-1251 pour la version russe, UTF-8 sur Linux/Mac).
5. Que faire en cas de mismatch d'encodage
Vous voyez des caractères illisibles. Vos étapes :
- Vérifiez dans quel encodage le fichier a été créé.
Ouvrez le fichier dans un éditeur qui montre l'encodage (par exemple Notepad++). - Indiquez explicitement l'encodage lors de la lecture/écriture.
Ne faites pas confiance au «par défaut», même si ça a toujours semblé fonctionner :
using var reader = new StreamReader("data.txt", Encoding.UTF8);
Faites attention au BOM.
- Si un autre logiciel exige le BOM — ajoutez-le (voir new UTF8Encoding(true)).
- Si ce n'est pas nécessaire — écrivez sans BOM (voir new UTF8Encoding(false)).
Exemple : mauvaise encodage à la lecture
// Le fichier a été créé en UTF-8, on le lit comme Windows-1251
using var reader = new StreamReader("test_utf8_no_bom.txt", Encoding.GetEncoding(1251));
var text = reader.ReadToEnd();
Console.WriteLine(text); // "Bonjour, le monde!" sera corrompu
6. Détails utiles
Le BOM dans les projets réels et en entretien
Si vous travaillez sur un projet où il faut sauvegarder des configs, des logs ou exporter des données, il vaut mieux se mettre d'accord tout de suite sur un encodage et le documenter. Ça peut sembler anecdotique, mais dès que ces fichiers sont lus par d'autres programmes ou personnes, un malentendu sur l'encodage crée plein de problèmes.
En entretien, le sujet du BOM et des «caractères bizarres au début d'un fichier» est presque un classique. Il est important non seulement de savoir ce qu'est le BOM, mais aussi d'expliquer pourquoi sa présence (ou son absence) impacte les intégrations et comment ça se relie au fait d'indiquer explicitement l'encodage.
Faites particulièrement attention aux échanges avec des systèmes externes sur d'autres OS ou écrits dans d'autres langages. Quelque part le BOM sera obligatoire, ailleurs il casse le parsing. Si vous ne prévoyez pas ça à l'avance, c'est difficile à traquer.
Recommandations et bonnes pratiques
- Indiquez toujours explicitement l'encodage quand vous travaillez avec des fichiers (ne comptez jamais sur le «par défaut»).
- Si vous avez besoin du BOM — utilisez new UTF8Encoding(true), si vous voulez sans BOM — new UTF8Encoding(false).
- Vérifiez les fichiers dans des éditeurs qui supportent plusieurs encodages (par exemple Notepad++, Visual Studio Code).
- Si vous recevez un fichier de l'extérieur — demandez aux collègues ou la doc dans quel encodage il a été créé.
- Si vous devez convertir un encodage ou enlever le BOM — faites-le explicitement.
Ce que voient différents programmes
| Fichier | Encodage d'écriture | Ouvert comme | Ce qu'on voit |
|---|---|---|---|
|
|
|
OK ("Привет, мир!") |
|
|
|
Caractères illisibles |
|
|
|
Caractères illisibles |
|
|
|
Les premiers octets sont altérés |
7. Comment vérifier et supprimer le BOM
Exemple : vérifier la présence d'un BOM
byte[] bytes = File.ReadAllBytes("test_utf8_bom.txt");
// Vérifions les 3 premiers octets
if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
{
Console.WriteLine("BOM trouvé ! Fichier en UTF-8 avec BOM.");
}
else
{
Console.WriteLine("Pas de BOM.");
}
Exemple : supprimer le BOM (si pour une raison quelconque il gêne)
if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
{
// Réécrit le fichier sans les 3 premiers octets
File.WriteAllBytes("no_bom.txt", bytes.Skip(3).ToArray());
}
8. Erreurs typiques et solutions
Les débutants sont souvent surpris quand leur programme commence à «bugger» en manipulant des fichiers texte. En général le souci vient du fait que le programme qui a écrit le fichier utilisait un encodage (ou un mode BOM) et le lecteur en utilise un autre. Par exemple, si vous avez écrit un fichier en UTF-8 sans BOM et que vous le lisez sous Windows où l'encodage système par défaut est Windows-1251, il n'est pas étonnant que tous les caractères deviennent illisibles. Il est crucial de toujours indiquer explicitement l'encodage. Si le fichier est destiné à être échangé entre programmes ou plateformes, utilisez un format universel — UTF-8 (ou UTF-8 avec BOM si un logiciel externe l'exige).
GO TO FULL VERSION