1. Niyə kodlaşdırmalar belə qarışıq olur?
Siz artıq bilirsiniz ki, mətn faylları — sadəcə bayt ardıcıllığıdır. Və C# (və .NET ümumilikdə) — hər hərfin öz yerində olmasını istəyən platformadır. Görünür, sadəcə oxumaqda və ya yazmada kodlaşdırmanı göstərmək yetərlidir — və hər şey qaydasına düşər. Amma real dünya o qədər də sadə deyil.
Kodlaşdırma ilə bağlı çaşqınlığın səbəbləri:
- Tarixi irs: Fayllar müxtəlif əməliyyat sistemlərində və redaktorlarda yaradıla bilər, hər biri "default" olaraq öz kodlaşdırmasını seçir.
- Çoxplatformalılıq: Windows-da yaradılmış fayl Linux və ya Mac-də oxunanda "default" kodlaşdırma fərqli ola bilər.
- BOM (Byte Order Mark): Faylın əvvəlində bəzən olan, bəzən olmayan xüsusi "başlıq". Proqramların faylı necə gördüyünə təsir edir.
2. BOM nədir və niyə lazımdır
Qısa izah
BOM (Byte Order Mark) — faylın əvvəlində olan xüsusi bayt ardıcıllığıdır, proqramlara deyir: "Salam! Mən bu kodlaşdırmadayam və baytlarımı belə oxu".
- BOM ən çox UTF-8, UTF-16 və UTF-32 kodlaşdırmalarında rast gəlinir.
- UTF-8-də BOM opsionaldır. Onun olması və ya olmaması proqramların faylı necə oxumasına təsir edə bilər.
| Kodlaşdırma | BOM (16-lıq görünüş) | Baytlar |
|---|---|---|
| UTF-8 | |
|
| UTF-16 LE | |
|
| UTF-16 BE | |
|
| UTF-32 LE | |
|
| UTF-32 BE | |
|
Kodlaşdırma məhkəməsindən fakt: ASCII və ANSI kodlaşdırmalarında BOM istifadə edilmir. Amma əgər orada görünərsə, köhnə proqramları çaşdıra bilər.
İllüstrasiya: BOM haradadır
+--------------------------+
| BOM | TEXT BYTES |
+--------------------------+
|EFBBBF| 48 65 6C 6C 6F | // "Hello" UTF-8-də BOM ilə
+--------------------------+
EF BB BF — UTF-8 üçün BOM. O faylın ən əvvəlinə yerləşir.
48 65 6C 6C 6F — mətnin adi baytlarıdır: "Hello" UTF-8-də (BOM olmasa da eyni görünərdi).
Nəticə: fayl EF BB BF ilə başlayır, sonra isə mətn gəlir.
3. Kodlaşdırma uyğunsuzluğu: "qarışıq simvollar" haradan gəlir
Tipik ssenari
- Siz faylı UTF-8 ilə yazırsınız, amma BOM olmadan.
- Windows redaktorunda açırsınız, o isə Windows-1251 və ya BOM-lu UTF-8 gözləyir.
- Nəticədə — "Salam, dünya!" əvəzinə "Привет, РјРёСЂ!" görürsünüz.
Niyə belə olur
- Proqram faylın bir kodlaşdırmada olduğunu düşünür, amma baytlar əslində başqa kodlaşdırmadadır.
- BOM hangi kodlaşdırma olduğunu təxmin etməyə kömək edə bilər. Amma əgər BOM yoxdursa, "təhqiqat" üsulu ilə təxmin edilir və nəticə — "qarışıq simvollar".
Uyğunsuzluq ssenarilərinin nümunələri:
- UTF-8 faylı Windows-1251 kimi oxuyursunuz — qeyri-ASCII simvollar abur-cubur olur.
- UTF-8 BOM ilə faylı "təmiz" UTF-8 kimi oxuyursunuz — adətən yaxşıdır, amma bəzi köhnə proqramlar faylın ilk simvollarını qəribə göstərə bilər.
- BOM ilə fayl yazırsınız, amma qarşı tərəf onu gözləmir — bəzi alətlər BOM-u sevmir və parse zamanı səhv yaranır.
4. Kodlaşdırma və BOM axınlarla işləməyə necə təsir edir
Nümunə: fərqli kodlaşdırmalarla fayl yazmaq və oxumaq
// UTF-8 ilə BOM-lu faylı yazırıq
using var writer = new StreamWriter("test_utf8_bom.txt", false, new UTF8Encoding(true));
writer.WriteLine("Salam, dünya!");
new UTF8Encoding(true) — BOM-u əlavə edir.
// UTF-8 ilə, BOM-suz faylı yazırıq
using var writer = new StreamWriter("test_utf8_no_bom.txt", false, new UTF8Encoding(false));
writer.WriteLine("Salam, dünya!");
new UTF8Encoding(false) — BOM yoxdur.
// Faylı kodlaşdırmanı açıq göstərərək oxumaq
using var reader = new StreamReader("test_utf8_no_bom.txt", new UTF8Encoding(false));
string line = reader.ReadLine();
Console.WriteLine(line);
Əgər fayl UTF-8 ilə və BOM olmadan yazılıbsa, kodlaşdırmanı açıq göstərmək düzgün oxumağı təmin edəcək.
Tipik səhv
Oxuyarkən kodlaşdırmanı göstərmədiyinizdə, StreamReader özü təxmin etməyə çalışacaq — əvvəlcə BOM-a baxır; yoxdur — sistemi default kodlaşdırmanı götürür (Windows-da rus versiyası üçün bu tez-tez Windows-1251, Linux/Mac-da isə adətən UTF-8).
5. Kodlaşdırma uyğunsuzluğu zamanı nə etmək lazımdır
'Qarışıq simvollar' görürsünüzsə atılacaq addımlar:
- Faylın hansı kodlaşdırmada yaradıldığını yoxlayın.
Kodlaşdırmanı göstərə bilən redaktorda açın (məsələn, Notepad++). - Oxuyarkən/yazarkən kodlaşdırmanı açıq göstər.
"Default"a güvənməyin, hətta əvvəl hər şey işləyirmiş kimi görünsə də:
using var reader = new StreamReader("data.txt", Encoding.UTF8);
BOM-u nəzərə alın.
- Əgər başqa proqram BOM tələb edirsə — əlavə edin (bax: new UTF8Encoding(true)).
- Əgər tələb etmirsə — BOM olmadan yazın (bax: new UTF8Encoding(false)).
Nümunə: oxuyarkən yanlış kodlaşdırma
// Fayl UTF-8-də yaradılıb, amma Windows-1251 kimi oxuyuruq
using var reader = new StreamReader("test_utf8_no_bom.txt", Encoding.GetEncoding(1251));
var text = reader.ReadToEnd();
Console.WriteLine(text); // "Salam, dünya!" korlanacaq
6. Faydalı nüanslar
BOM real layihələrdə və müsahibələrdə
Konfiq, log və ya data export edən layihədə işləyirsinizsə, kodlaşdırmanı dərhal müəyyən edin və sənədləşdirin. Bu kiçik görünə bilər, amma faylları başqaları və ya xarici proqramlar oxuyanda kodlaşdırma anlaşılmazlığı böyük problemlərə gətirib çıxara bilər.
Müsahibələrdə BOM və "faylın əvvəlində qəribə simvollar" mövzusu demək olar ki, əksər hallarda çıxır. Vacib olan yalnız BOM-un nə olduğunu bilmək deyil, həm də onun mövcudluğunun (və ya olmamasının) inteqrasiya üçün niyə vacib olduğunu izah etməkdir.
Xarici sistemlər və ya fərqli OS/language ilə məlumat mübadiləsində diqqətli olun. Hardasa BOM zəruridir, hardasa isə o parse-ı pozur. Əvvəlcədən bunu nəzərə almazsanız, problemi tapmaq çətin olacaq.
Tövsiyələr və ən yaxşı təcrübələr
- Fayllarla işləyərkən kodlaşdırmanı açıq göstər (heç vaxt "default"a güvənmə).
- Əgər BOM lazımdırsa — new UTF8Encoding(true)-dən istifadə et, lazım deyilsə — new UTF8Encoding(false).
- Faylları müxtəlif kodlaşdırmaları dəstəkləyən redaktorlarda yoxla (məsələn, Notepad++, Visual Studio Code).
- Xaricdən fayl gəlirsə — həmkarlardan və ya sənədləşmədən hansı kodlaşdırmada yaradıldığını dəqiqləşdir.
- Kodlaşdırmanı konvertasiya etmək və ya BOM-dan qurtulmaq lazım gəlsə — bunu açıq şəkildə et.
Fərqli proqramlar nə görür
| Fayl | Yazılma kodlaşdırması | Açırıq kimi | Nə görərik |
|---|---|---|---|
|
|
|
OK ("Salam, dünya!") |
|
|
|
Qarışıq simvollar |
|
|
|
Qarışıq simvollar |
|
|
|
İlk baytlar pozula bilər |
7. BOM-u necə yoxlamaq və silmək
Nümunə: BOM-un olub-olmadığını yoxlamaq
byte[] bytes = File.ReadAllBytes("test_utf8_bom.txt");
// İlk 3 baytı yoxlayaq
if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
{
Console.WriteLine("BOM tapıldı! Bu UTF-8 BOM ilədir.");
}
else
{
Console.WriteLine("BOM yoxdur.");
}
Nümunə: BOM-u silmək (əgər lazım gəlsə)
if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
{
// İlk 3 baytı çıxarıb faylı yenidən yazırıq
File.WriteAllBytes("no_bom.txt", bytes.Skip(3).ToArray());
}
8. Tipik səhvlər və onların həlli yolları
Yeni başlaymış proqramçılar adətən mətn faylları ilə işləyərkən proqramın birdən-birə "donduğunu" görəndə təəccüblənirlər. Adətən problem mənbəyi budur ki, yaradılan proqram bir kodlaşdırma və ya BOM rejimi istifadə edib, oxuyan proqram isə fərqli. Məsələn, faylı UTF-8 BOM-suz yazmısınız, amma Windows-da oxuyursunuz və sistemin default kodlaşdırması Windows-1251-dir — ona görə simvollar qarışır. Həmişə kodlaşdırmanı açıq göstərmək çox vacibdir. Fayl müxtəlif proqramlar və platformalar arasında mübadilə üçün nəzərdə tutulubsa, universal format istifadə edin — UTF-8 (və ya xarici proqram tələb edirsə UTF-8 ilə BOM).
GO TO FULL VERSION