JavaRush /Курси /C# SELF /Задання кодування під час читання й запису (

Задання кодування під час читання й запису ( Encoding)

C# SELF
Рівень 37 , Лекція 2
Відкрита

1. Кодування за замовчуванням

Коли ви працюєте зі StreamReader або StreamWriter, вони використовують кодування за замовчуванням.

Якщо ви пишете:

using var reader = new StreamReader("myfile.txt");

або

using var writer = new StreamWriter("output.txt");

.NET обирає кодування за замовчуванням. У Windows це зазвичай UTF-8 (часто без BOM), але в старих застосунках або під час запуску на інших системах поведінка може відрізнятися.

У більшості випадків UTF-8 — вдалий вибір: він підтримує всі мови й компактно зберігає англомовний текст (а також тексти багатьма європейськими мовами). Але якщо файл створений в іншому кодуванні (наприклад, у Windows-1251) або його читатимуть інші програми, які очікують певне кодування, вам слід явно вказати потрібне кодування.

2. Вказання кодування для StreamReader і StreamWriter

Варіанти конструкторів

І StreamReader, і StreamWriter підтримують конструктори, до яких можна передати об’єкт типу System.Text.Encoding.

Приклад:

using var reader = new StreamReader("myfile.txt", Encoding.UTF8);
using var writer = new StreamWriter("output.txt", false, Encoding.UTF8);

Якщо хочете працювати з ASCII, Windows-1251 або UTF-16, просто підставте інше кодування:

using var reader = new StreamReader("myfile.txt", Encoding.Unicode); // UTF-16
using var reader2 = new StreamReader("rus.txt", Encoding.GetEncoding("windows-1251"));

Коротка таблиця популярних кодувань:

Кодування C#-вираз Опис
UTF-8
Encoding.UTF8
Підтримує всі мови, компактне
UTF-16 (Unicode)
Encoding.Unicode
Стандарт .NET, 2 байти на символ
ASCII
Encoding.ASCII
Лише базові символи (англ.)
Windows-1251
Encoding.GetEncoding("windows-1251")
Кирилиця; старі програми для Windows

Увага! Для нестандартних кодувань на кшталт Windows-1251 використовуйте метод Encoding.GetEncoding("windows-1251").

3. Читаємо і пишемо з вказанням кодування

Додаймо до нашого мінізастосунку новий функціонал: нехай він читає файл у вказаному кодуванні й записує результат до нового файлу, теж із явно заданим кодуванням. Так можна, наприклад, конвертувати текст між різними системами!

Приклад 1: Читання файлу у кодуванні Windows-1251 і виведення на екран

// Припустімо, файл створено в кодуванні Windows-1251
using var reader = new StreamReader("ru_text.txt", Encoding.GetEncoding("windows-1251"));

string line;
while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line);
}

Чому це важливо: Якби ми не вказали кодування, замість кириличних літер отримали б жахливі символи типу "Учебник".

Приклад 2: Запис файлу в UTF-16 (Unicode)

using var writer = new StreamWriter("utf16text.txt", false, Encoding.Unicode);
writer.WriteLine("Привіт, світ!");
writer.WriteLine("Hello, world!");
writer.WriteLine("こんにちは世界");

Результат: Відкривши файл, наприклад, у Notepad, ви побачите, що всі символи чудово відображаються.

4. Невеличка утиліта для конвертації кодувань

Завдання (його часто ставлять на співбесідах!): Перетворити текстовий файл із кодування Windows-1251 у UTF-8.

string sourcePath = "ru_text_1251.txt";
string destPath = "ru_text_utf8.txt";

// Читаємо у кодуванні Windows-1251
using var reader = new StreamReader(sourcePath, Encoding.GetEncoding("windows-1251"));
// Записуємо у UTF-8
using var writer = new StreamWriter(destPath, false, Encoding.UTF8);

string? line;
while ((line = reader.ReadLine()) != null)
    writer.WriteLine(line);

Тепер ru_text_utf8.txt можна без проблем відкривати у Visual Studio Code, у Linux, на Mac і бачити читабельний текст.

5. Корисні нюанси

Як дізнатися, у якому кодуванні файл?

Це запитання з підступом! Сам файл зазвичай не містить усередині інформацію про своє кодування (виняток — файли з BOM, про це детальніше в наступній лекції). Якщо ви відкриваєте файл у неправильному кодуванні, результат — каракулі.

Типові практичні підходи:

  • Якщо файл був створений вашою програмою — завжди використовуйте те саме кодування для читання, що й під час запису.
  • Якщо файл прийшов з невідомого джерела — спробуйте різні кодування або скористайтеся сторонніми утилітами, щоб його визначити.

Робота з емодзі та незвичними символами

UTF-8 і UTF-16 дозволяють вільно використовувати емодзі та символи з різних мов світу. Спробуйте зберегти файл з емодзі у UTF-8, а потім відкрити його в застарілому кодуванні — буде весело (або й ні)!

Код із емодзі:

using var writer = new StreamWriter("emoji.txt", false, Encoding.UTF8);
writer.WriteLine("Привіт 👋😀🌍");

StreamReader з автоматичним визначенням кодування

Конструктор StreamReader має перевантаження з параметром detectEncodingFromByteOrderMarks:

new StreamReader(path, encoding, detectEncodingFromByteOrderMarks: true)

Якщо цей параметр дорівнює true (це значення за замовчуванням!), StreamReader намагатиметься визначити кодування файлу за наявністю BOM (спеціальної «мітки» на початку файлу). Але якщо файл створено без BOM або в екзотичному кодуванні, визначення може не спрацювати.

Коли і навіщо варто явно вказувати кодування?

  • Багатомовні дані: підтримка арабської, китайської, емодзі тощо.
  • Інтеграції: файл читається/записується не лише вашою програмою, а й сторонньою системою, яка очікує певне кодування.
  • Розмір файлу важливий: ASCII/UTF-8 економніші для латиниці, UTF-16 — для ієрогліфів.
  • Сумісність: журнали/експорт для інших застосунків.

6. Типові помилки під час роботи з кодуваннями

Помилка № 1: відсутність явного вказання кодування під час читання файлу.
Читання файлу з нелатинським текстом без вказання кодування часто призводить до незрозумілої «абракадабри».

Помилка № 2: невідповідність кодувань під час запису та читання.
Файл було записано в одному кодуванні, а відкрито в іншому — у результаті отримуємо спотворений текст. Часто це трапляється під час перенесення між різними ОС чи програмами.

Помилка № 3: непідтримувані або частково підтримувані кодування.
Деякі редактори некоректно працюють з UTF-8 без BOM або зі старими однобайтовими кодуваннями, такими як Windows-1251. Іноді доводиться вручну перемикати кодування і експериментувати.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ