JavaRush /Курси /C# SELF /Формати файлів: Текстові та Бінарні

Формати файлів: Текстові та Бінарні

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

1. Текстові файли

Згадайте: компʼютер усе, абсолютно все, зберігає як одиниці та нулі (або, якщо формально — як послідовність байтів). Однак дві різні програми можуть по‑різному відреагувати на один і той самий файл. Наприклад, одна програма побачить у ньому звичайний текст, а інша — набір «битих байтів». Річ у форматі файлу — у тому, як саме ці байти інтерпретуються. Формат описує внутрішню структуру даних, правила їхнього читання та кодування. Без знання формату програма може просто не зрозуміти, що саме зберігається у файлі.

Текстовий файл — це файл, у якому дані подано звичайним текстом у певному кодуванні (найчастіше — UTF-8, інколи — ASCII). Вміст такого файлу можна відкрити в будь-якому текстовому редакторі (наприклад, у Notepad чи VS Code) і одразу прочитати: це рядки символів, а не керівні байти чи бінарні структури.

Типові приклади

  • *.txt — звичайні текстові файли, наприклад «to-do.txt» або «best-books.txt».
  • *.csv — файли, де дані розділені комами або крапками з комою (зручно для таблиць).
  • *.json — файли для обміну структурованими даними (наприклад, списки книжок).
  • *.xml, *.html — для зберігання та передавання структурованих даних.

Приклад CSV-файлу


Дюна;Френк Герберт;1965
1984;Джордж Орвелл;1949
Майстер і Маргарита;Михайло Булгаков;1966
Приклад вмісту books.txt (CSV-формат)

Кожен рядок — це окремий запис (наприклад, книжка). Значення всередині рядка розділено крапкою з комою, тож файл відповідає формату CSV (Comma-Separated Values). Хоча «comma» — це кома, у цьому прикладі роздільник інший — крапка з комою (;). Символи, які бачить людина, — ті самі байти, що читає й програма, якщо вона знає, як інтерпретувати текстовий формат і кодування файлу.

Як програма працює з текстовим файлом

Достатньо відкрити файл «як текст», і можна читати його пострічково. Приклад (згодиться в майбутніх лекціях):


// Просте читання рядків із файлу (деталі розглянемо згодом)
string[] lines = File.ReadAllLines("books.txt");
foreach (string line in lines)
{
    Console.WriteLine(line);
}

Переваги текстових файлів

  • Зрозумілі людині (human-readable).
  • Легко редагувати вручну (навіть у найпростішому застосунку на кшталт Notepad).
  • Чудово підходять для налагодження та обміну між різними системами.
  • Легко переносити між різними платформами (Windows, Linux, macOS).

Недоліки текстових файлів

  • Немає суворої структури (txt), помилки форматування легко внести випадково.
  • Займають більше місця (наприклад, число 12345 = 5 байт, а у бінарному форматі — 4 байти).
  • Складні дані (наприклад, зображення, аудіо) через текст передавати незручно або неможливо.
  • Продуктивність: повільніше для великих обсягів даних.

Корисно знати

  • Різні платформи по-різному розуміють «кінець рядка»: Windows — \r\n, Unix — \n.
  • Кодування можуть відрізнятися (UTF-8, UTF-16, ANSI тощо), а отже, файл, записаний в одній системі, може відображатися «незрозумілими символами» в іншій (насправді це просто неправильна інтерпретація байтів).

2. Бінарні файли

Бінарний файл — це файл, у якому зберігаються не символи, а довільні байти. Вони можуть означати що завгодно: числа, структури, зображення, музику, навіть машинний код. Спробуйте відкрити .exe у Блокноті — побачите набір незрозумілих символів.

Типові приклади

  • *.exe, *.dll — виконувані файли та бібліотеки.
  • *.jpg, *.png, *.gif — зображення.
  • *.mp3, *.wav — аудіофайли.
  • *.dat — файли з довільними користувацькими даними.
  • Специфічні для застосунків формати (*.docx, *.xlsx тощо) — майже завжди бінарні.

Як влаштований бінарний файл?

Програма записує й читає дані байт за байтом у потрібному їй форматі. Наприклад, число типу int займе 4 байти (32 біти), а рядок зазвичай — це довжина та байти символів у певному кодуванні.

У текстовому файлі число 12345 — це байти, що відповідають символам «1», «2», «3», «4», «5»:

Символ Код UTF-8
1 49
2 50
3 51
4 52
5 53

У бінарному файлі int 12345 (малий порядок байтів, little-endian) буде так:

Позиція Байт (hex) Значення
0 0x39 57
1 0x30 48
2 0x00 0
3 0x00 0

(Іншими словами: 12345 = 0x00003039.)

Спробуйте записати в текстовому і бінарному вигляді одне й те саме число — і порівняйте розмір файлів. Бінарний буде трохи компактніший.

Як програма працює з бінарним файлом

Для роботи з такими файлами використовують спеціальні потоки (наприклад, BinaryReader та BinaryWriter). На відміну від текстового формату, тут потрібно точно знати структуру; інакше прочитати дані не вдасться.


// Приклад запису чисел у бінарний файл
var writer = new BinaryWriter(File.Open("books.bin", FileMode.Create));

// Припустимо, записуємо рядок: кількість символів (int), потім байти
string title = "Дюна";
writer.Write(title.Length); // Записали довжину (int)
writer.Write(title); // Записали рядок (буде в UTF-8)
writer.Write(1965); // Записали рік (int)

writer.Close(); // Закриваємо потік

Це лише приклад. Детальніше про роботу з бінарними файлами розглянемо в найближчих лекціях.

Переваги бінарних файлів

  • Компактність: займають менше місця.
  • Швидше зчитуються і записуються (особливо для великих обсягів даних).
  • Можна зберігати складні структури: масиви, вкладені обʼєкти тощо.

Недоліки бінарних файлів

  • Нечитабельні для людини (human-unreadable).
  • Якщо структура файлу змінилася, старі дані можуть бути втрачені або пошкоджені.
  • Завжди потрібні точні інструкції для розбору вмісту.

3. Який формат обрати?

Текстові vs Бінарні файли

Критерій Текстовий файл Бінарний файл
Зрозумілий людині Так Ні
Розмір Більший Менший
Універсальність Висока (будь-який редактор) Лише спец. програми
Швидкість Повільніше Швидше
Суворість формату Ні Так, обовʼязково дотримуватися
Зберігання структур Складно Легко
Ризик псування даних Низький (легко редагувати) Високий (найменший збій — файл не читається)

Критерії вибору

  • Потрібно, щоб дані були зрозумілі людині, їх легко змінювати й налагоджувати? — Використовуйте текстовий файл (наприклад, .txt, .csv, .json).
  • Дані складні, важливі розмір і швидкість? — Бінарний формат.
  • Потрібно обмінюватися даними між різними платформами? — Текстовий формат кращий, але кодування має бути стандартним (UTF-8).
  • Застосунок читатиме й записуватиме багато даних, і формат суворий? — Обирайте бінарний.

У нашому консольному застосунку «Список книжок» на перших порах ідеально підійде текстовий формат (.csv або .txt). Пізніше, коли структура ускладниться або виникне потреба підвищити швидкість завантаження, можна вивчити бінарні файли або перейти на формат JSON/XML.

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

Де в житті зустрічаються текстові та бінарні файли?

Текстові файли:

  • Налаштування програм (часто у .ini або .json).
  • Скрипти, журнали, нотатки.
  • Файли імпорту/експорту (дані для обміну між застосунками).

Бінарні файли:

  • Програми, ігри, бібліотеки (їхній вміст нечитабельний для людини).
  • Великі бази даних і архіви (наприклад, .mdb, .zip).
  • Медіа: музика, фото, відео.

Читання всього файлу одразу (текстове представлення):


string allText = File.ReadAllText("books.txt");
// Тепер allText — суцільний рядок з усім вмістом

Пострічково (оптимально для списків):


string[] lines = File.ReadAllLines("books.txt");
foreach (string line in lines)
{
    // Можна розбивати рядок на частини
    string[] parts = line.Split(';');
    // parts[0] — назва, parts[1] — автор, parts[2] — рік
}

Бінарне читання — суворо за структурою


var reader = new BinaryReader(File.Open("books.bin", FileMode.Open));

int count = reader.ReadInt32(); // Скільки книжок
for (int i = 0; i < count; i++)
{
    string title = reader.ReadString();
    string author = reader.ReadString();
    int year = reader.ReadInt32();
    // Тепер можна відновити запис!
}

reader.Close();

5. Практичний приклад: створюємо файл з книжками

Зберігаємо дані у текстовий файл

Зберігатимемо кожну книжку в рядку такого формату:
назва;автор;рік першого видання


// Список книжок, який ми хочемо зберегти
var books = new List<(string Title, string Author, int Year)>
{
    ("Дюна", "Френк Герберт", 1965),
    ("1984", "Джордж Орвелл", 1949),
    ("Майстер і Маргарита", "Михайло Булгаков", 1966)
};

// Зберігаємо у текстовий файл
var writer = new StreamWriter("books.txt");
foreach (var book in books)
    writer.WriteLine($"{book.Title};{book.Author};{book.Year}");

writer.Close();

Ви можете відкрити books.txt у Блокноті й побачити всі дані.

Зберігаємо дані у бінарний файл

А тепер спробуємо те саме, але компактніше (хоч і непридатно для читання людиною):


var writer = new BinaryWriter(File.Open("books.bin", FileMode.Create));

writer.Write(books.Count); // Запишемо кількість книжок
foreach (var book in books)
{
    writer.Write(book.Title); // Рядок зберігатиметься як: довжина + байти
    writer.Write(book.Author); // Рядок
    writer.Write(book.Year); // Рік (int)
}

writer.Close();

Якщо спробувати відкрити books.bin у текстовому редакторі, ви побачите хаос: набір незрозумілих символів. Це нормально. Бінарні файли не призначені для читання людиною — їх може правильно обробити лише програма, яка точно знає, як цей файл було записано.

6. Типові помилки при роботі з форматами

Якщо спробувати прочитати бінарний файл як текстовий, ви отримаєте «кашу» з символів або взагалі помилку. Аналогічно, якщо відкривати текстовий файл як бінарний і очікувати сувору структуру — будуть проблеми.

Найчастіша помилка: порушення відповідності між структурою даних і порядком читання/запису. Наприклад, спочатку записали рік, потім назву, а читаєте навпаки — отримаєте не ту інформацію. Завжди дотримуйтеся одного й того самого порядку операцій!

Часто розробники «підглядають» у текстовий файл, перевіряючи логіку збереження і завантаження — саме тому текстові формати зручні на перших кроках. Бінарний формат підходить для складніших сценаріїв або коли потрібно приховати деталі зберігання від користувача.

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