CodeGym /Kurslar /C# SELF /Faylların kodlaşdırmalarının çevrilməsi

Faylların kodlaşdırmalarının çevrilməsi

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Əsas sualla başlayaq — ümumiyyətlə kodlaşdırmalarla niyə məşğul olmaq lazımdır? Görünür, bir fayl, bir kodlaşdırma və hər şey sakit olmalıdır. Amma reallıqda vəziyyət daha maraqlıdır. Tez-tez ortaya çıxır ki, fayl haradan gəldiyi məlum olmayan və tam gözlənilməz kodlaşdırmada ola bilər. Və proqramınız isə tamamilə başqa kodlaşdırmanı gözləyir.

Bəzən müəyyən API və ya sistemlə inteqrasiya etməlisiniz və orada sərt tələblər olur: məhz bu kodlaşdırma və başqa heç nə. Bəzən isə on yaşlı köhnə faylı yeni redaktorda açırsan — və orada krakozyabry. Və ya siz CSV-hesabat saxlayırsınız və istəyirsiniz ki, hamı — həm Windows, həm Mac, hətta Excel — onu düzgün oxusun.

Nəticə: rekodlaşdırma nadir və ekzotik iş deyil. Əksinə, çox real və tez-tez rastlanan vəzifədir — verilənlər bazasından çıxarışlarda, arxivlə işləmədə, mühasibatlıqla inteqrasiyada və avtomatlaşdırılmış skriptlərdə. Neçə əvvəl bunu həll etsəniz, sonradan bir o qədər az sürprizlə qarşılaşarsınız.

Köhnə kodlaşdırmadan yeni kodlaşdırmaya

Faylı yenidən kodlaşdırmaq üçün iki addım etməlisiniz:

  1. Oxumaq — faylı ilkin kodlaşdırmada oxumaq, stringlər (və ya simvollar) əldə etmək.
  2. Yazmaq — stringləri yeni fayla yazmaq, məqsəd kodlaşdırmanı açıq şəkildə göstərərək.

Analogi: kitabı fransızcadan ruscaya tərcümə edirsiniz. Əvvəlcə fransızca oxumağı bacarmalısınız (mətn oxumaq), sonra həmin mənanı rus dilində ifadə etməlisiniz (mətn yazmaq).

C# (və .NET)-də bunu StreamReader (oxumaq üçün) və StreamWriter (yazmaq üçün) konstruktorunda uyğun Encoding obyekti qoymaqla həyata keçirirsiniz.

Kodlaşdırmaların icmalı və Encoding sinfi

Bütün “sehrli” simvol çevirmələri System.Text.Encoding sinfi vasitəsilə həyata keçirilir.

Əsas kodlaşdırmaların cədvəlini və C#-da onları necə almağı belə göstərə bilərik:

Kodlaşdırma Təsvir C# konstantası
UTF-8 Universal, defolt üzrə BOM-suz
Encoding.UTF8
UTF-8 ilə BOM Eynidir, amma BOM imzası ilə
new UTF8Encoding(true)
UTF-16 (LE/BE) "Wide char", little-endian Encoding.Unicode (LE),
Encoding.BigEndianUnicode (BE)
ASCII 7-bit klassika
Encoding.ASCII
Windows-1251 Kiril üçün məşhurdur
Encoding.GetEncoding(1251)
ISO-8859-1 Latın (avropa)
Encoding.GetEncoding("ISO-8859-1")

Qeyd: Köhnə kodlaşdırmalar üçün Encoding.GetEncoding-dən istifadə etmək lazım olacaq, bəzən nömrə ilə (1251), bəzən sətr ilə ("windows-1251").

2. Rekodlaşdırma: C#-də addım-addım strategiya

Gəlin praktikada rekodlaşdırmanın necə həyata keçirildiyini öyrənək.

Alqoritm

  1. Mənbə faylı StreamReader vasitəsilə açın, başlanğıc kodlaşdırmanı açıq göstərin.
  2. Mətn oxuyun (tam və ya sətir-sətir — faylın ölçüsündən asılı).
  3. Çıxış faylını StreamWriter ilə açın, istədiyiniz son kodlaşdırmanı göstərin.
  4. Mətn çıxış faylına yazın.
  5. Axınları bağlamağı unutmayın — etibarlı olmaq üçün using istifadə edin!

Nümunə: Windows-1251 → UTF-8 rekodlaşdırma

Məsələn, bizdə Windows-1251 kodlaşdırmalı "input-1251.txt" faylı var və biz onu “təmiz” UTF-8 (BOM-suz) şəklində "output-utf8.txt"-ə çevirmək istəyirik.

// Mənbəni başlanğıc kodlaşdırma ilə göstəririk
using var reader = new StreamReader("input-1251.txt", Encoding.GetEncoding(1251));
using var writer = new StreamWriter("output-utf8.txt", false, Encoding.UTF8);

string line;
// Böyük fayllar üçün sətir-sətir oxumaq rahatdır
while ((line = reader.ReadLine()) != null)
{
    writer.WriteLine(line);
}

Console.WriteLine("Fayl Windows-1251-dən UTF-8-ə uğurla rekodlaşdırıldı!");

Bu kod hər sətirin bir kodlaşdırmadan digərinə düzgün çevrilməsini təmin edir.

Şematik olaraq belə görünür:


┌───────────────────────────────┐     ┌───────────────────┐     ┌───────────────────────────────┐
│ "input-1251.txt" faylı (1251) │ --> │  StreamReader     │ --> │  Yadda string tipində sətirlər │
└───────────────────────────────┘     │ (Encoding 1251)   │     └───────────────────────────────┘
                                      └───────────────────┘
                                              │
                                              ▼
                                  ┌────────────────────────┐
                                  │   StreamWriter         │
                                  │   (Encoding UTF-8)     │
                                  └───────────┬────────────┘
                                            │
                                            ▼
                              ┌──────────────────────────────┐
                              │ "output-utf8.txt" (UTF-8)     │
                              └──────────────────────────────┘

3. Praktik nümunə: kodlaşdırma konverteri

Gəlin işi bir az çətinləşdirək: istifadəçi mənbə və təyinat faylını, həmçinin kodlaşdırmaları seçə bilən sadə konverter yazırıq.

Console.WriteLine("İlkin fayla olan yolu daxil edin:");
string inputPath = Console.ReadLine();

Console.WriteLine("İlkin faylın kodlaşdırması (məsələn, 1251, utf-8):");
string sourceEncodingName = Console.ReadLine();

Console.WriteLine("Təyinat fayla olan yolu daxil edin:");
string outputPath = Console.ReadLine();

Console.WriteLine("Saxlama üçün kodlaşdırma (məsələn, utf-8, 1251):");
string destEncodingName = Console.ReadLine();

Encoding sourceEncoding = Encoding.GetEncoding(sourceEncodingName);
Encoding destEncoding = Encoding.GetEncoding(destEncodingName);

using var reader = new StreamReader(inputPath, sourceEncoding);
using var writer = new StreamWriter(outputPath, false, destEncoding);
string line;
while ((line = reader.ReadLine()) != null)
{
    writer.WriteLine(line);
}

Console.WriteLine("Hazırdır! Nəticəni yoxlayın.");

Məsləhət: Hansı kodlaşdırmanı göstərəcəyinizdən əminsinizsə, sənədləşməyə baxın və ya müxtəlif variantları sınayın. Bəzən faylı yalnız eksperimental olaraq "tapmaq" olur, əgər heç kim README qoymayıbsa.

4. Vacib nüanslar: BOM, "görünməz" simvollar və xüsusi hallar

UTF-8 yazarkən BOM necə əlavə etmək olar?

Defolt olaraq Encoding.UTF8 C#-da fayllar yaradır BOM-suz. Əgər BOM ilə fayl yaratmaq lazımdırsa, istifadə edin:

// true — deməkdir "BOM ilə"
var utf8WithBom = new UTF8Encoding(true);

using var writer = new StreamWriter("with-bom.txt", false, utf8WithBom);
writer.WriteLine("BOM ilə mətn");

Fayl indi başında “görünməz” üç baytla başlayacaq: 0xEF, 0xBB, 0xBF.

BOM nə vaxt zərərlidir?

  • CSV-ni Excel üçün ixrac edirsinizsə, xarici variantlarda BOM çox vaxt problem yaradır — qəribə simvollar görünə bilər.
  • Unix-oxşar sistemlərdə (Linux) BOM faylın emalını poza bilər.
  • JSON faylları üçün BOM demək olar ki, həmişə zərərlidir, bir çox parser onu qəbul etmir!

Məsləhət: BOM lazımdır yoxsa yox — şüurlu seçin və yalnız lazım olduqda əlavə edin.

Gizlənmiş simvollar və sehrli ədədlər

Əgər rekodlaşdırılmış faylı açanda proqram format xətası verirsə, bəlkə başlanğıcdakı “görünməz” simvolları (məsələn, BOM) nəzərə almamısınız və ya kodlaşdırmanı səhv seçmisiniz (məsələn, faylı ASCII kimi oxumusunuz, amma orada 1251-də kiril var). Həmişə yoxlayın ki, tətbiqiniz/kolleganız/server hansı kodlaşdırmadan istifadə edir.

5. Faydalı nüanslar

Böyük fayllarla iş: niyə sətir-sətir, bütününü deyil?

Sadəcə belə də yazmaq olardı:

string allText = File.ReadAllText("input.txt", Encoding.GetEncoding(1251));
File.WriteAllText("output.txt", allText, Encoding.UTF8);

Bu yanaşma kiçik və orta fayllar üçün uyğundur (məsələn, 50 MB-dək). Amma fayl böyükdürsə, bütün mətn əməliyyat sisteminin yaddaşına yüklənəcək — və əgər fayl bir neçə GB-dırsa, pis nəticə olar. Buna görə də universal olmaq üçün sətir-sətir oxuma/yazma istifadə edirik.

Daha az yayılmış kodlaşdırmalar arasında rekodlaşdırma

Tutaq ki, sizdə birdən ISO-8859-1 kodlaşdırmalı fayl peyda oldu (MySQL-ə bənzər bazalar bunu edir), və onu Unicode-a çevirməlisiniz.

var sourceEnc = Encoding.GetEncoding("iso-8859-1");
var destEnc = Encoding.UTF8;

using var reader = new StreamReader("data-latin.txt", sourceEnc);
using var writer = new StreamWriter("data-unicode.txt", false, destEnc);
string line;
while ((line = reader.ReadLine()) != null)
{
    writer.WriteLine(line);
}

Bu yanaşma .NET dəstəklədiyi hər hansı kodlaşdırma ilə işləyir.

İkilik (binary) faylları rekodlaşdırmaq — lazım deyil!

Yuxarıda təsvir olunmuş proqram yalnız mətn faylları üçün nəzərdə tutulub. Fayl ikilikdirsə (məsələn, şəkil, audio, arxiv), onu “mətin kimi oxuyub sonra yazmaq” cəhdləri baytları pozacaq, krakozyabrlara səbəb olacaq və fayl işləməz olacaq. İkilik fayllar üçün rekodlaşdırma məntiqsizdir.

Uyğunluq cədvəli: hansı kodlaşdırma nə üçün uyğun

Kodlaşdırma Nə vaxt istifadə etmək
UTF-8 Universal fayllar, web, müasir tətbiqlər
UTF-8 ilə BOM Notepad, Excel ilə uyğunluq üçün
Windows-1251 Köhnə məktəb üçün, rus dilində lokal proqramlar
ASCII Yalnız ingilis mətni olan fayllar üçün
UTF-16 Xüsusi hallarda, ekzotik tətbiqlər üçün

Köməkçi “triklər” və məsləhətlər

Faylın kodlaşdırmasını necə öyrənmək olar?

  • Notepad++, Visual Studio Code kimi xüsusi redaktorlar tez-tez kodlaşdırmanı müəyyən edib göstərirlər.
  • Əgər BOM yoxdursa və hər şey “görünür” amma hərflər yanlışsa — çox güman kodlaşdırma uyğun deyil.

Kodlaşdırmanın avtomatik təyini mümkündürmü?

  • .NET-də hər bir fayl üçün 100% düzgün kodlaşdırmanı müəyyən edən sihirli funksiya yoxdur. Adətən qayda belədir: əgər BOM varsa, bu açıq-aydındır; əks halda məzmun üzrə və ya fərqli variantları sınayaraq nəticəyə gəlmək lazımdır.

Əgər bəzi sətirlər düzgün oxunur, bəziləri isə “krakozyabry”dırsa, nə etməli?

  • Bəlkə fayl mürəkkəb yığılmışdır və ya zədələnib. Yoxlayın ki, fayl müxtəlif proqramlarla yazılmayıb.

6. Tipik səhvlər və onlardan necə qaçmaq

İşin rahat getməsi üçün ən çox rastlanan səhvləri nəzərdən keçirək:

Yanlış başlanğıc kodlaşdırma. Faylın UTF-8 olduğunu zənn edirsiniz, amma əslində Windows-1251-dir — kiril əvəzinə “pillə” görəcəksiniz. Əgər əminsinizsə, Notepad++ və ya oxşar redaktorlarda yoxlayın.

BOM səhv yerdə. Bəzən BOM əlavə etmək parsing-i pozur, bəzən isə BOM olmaması digər proqram tərəfindən səhv konkretləşdirməyə gətirib çıxarır.

Faylı tam yaddaşa oxumaq. Fayl böyükdürsə, sətir-sətir oxuyun — əks halda proqram böyük mətn bazasına görə bütün RAM-ı istehlak edə bilər.

Kodlaşdırma göstərmədən yazmaq. Defolt olaraq StreamWriter UTF-8 BOM-suz istifadə edir. Başqa variant istəyirsinizsə — kodlaşdırmanı açıq şəkildə göstərin.

GetEncoding-in yanlış istifadəsi. Əgər sətir səhvdirsə, məsələn, "utf8" əvəzinə "utf-8" yazsanız, exception alacaqsınız. Düzgün adlardan (və ya koda, məsələn 1251) istifadə edin.

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Əsas kodlaşdırma tipləri
Faylların kodlaşdırılması ilə işləmək
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION