1. Текстовые файлы
Вспомните: компьютер всё, абсолютно всё, хранит как единицы и нули (или, если не боитесь страшного слова — как последовательность байтов). Но если скормить двум программам один и тот же файл, не факт, что они на него одинаково отреагируют. Скажем, одна программа увидит в нём обычный текст, а другая — набор "бракованных байтов". Всё дело в формате файла — в том, как именно эти байты интерпретируются. Формат описывает внутреннюю структуру данных, правила их чтения и кодировку. Без знания формата программа может просто не понять, что именно хранится в файле.
Текстовый файл — это файл, данные в котором представлены обычным текстом в какой-либо кодировке (чаще всего — UTF-8 или, если уж совсем по хардкору — ASCII). Содержимое такого файла можно открыть в любом текстовом редакторе (например, в Notepad или VS Code) и сразу прочитать — это строки символов, а не загадочные управляющие байты или бинарные структуры.
Типичные примеры
- *.txt — обычные текстовые файлы, например "to-do.txt" или "best-books.txt".
- *.csv — файлы, где данные разделены запятыми или точками с запятой (удобно для таблиц).
- *.json — файлы для обмена структурированными данными (например, списки книг).
- *.xml,*.html — для хранения и передачи структурированных данных.
Пример CSV-файла
Дюна;Фрэнк Герберт;1965
1984;Джордж Оруэлл;1949
Мастер и Маргарита;Михаил Булгаков;1966
Каждая строка — это отдельная запись (например, книга). Значения внутри строки разделены точкой с запятой, что делает файл примером CSV (Comma-Separated Values). Comma — это вроде как запятая, но запятая в данном случае заменена на другой разделитель (;). Символы, которые видит человек, — это те же байты, что читает и программа, при условии, что она знает, как интерпретировать текстовый формат и кодировку файла.
Как программа работает с текстовым файлом
Достаточно открыть файл "как текст", и можно читать построчно. Пример (который пригодится вам в будущих лекциях):
// Простое чтение строк из файла (детали скоро разберём)
string[] lines = File.ReadAllLines("books.txt");
foreach (string line in lines)
{
Console.WriteLine(line);
}
Преимущества текстовых файлов
- Читаемы человеком (human-readable).
- Легко редактировать вручную (даже в самом простом приложении типа Notepad).
- Прекрасно подходят для отладки и обмена между разными системами.
- Легко переносить между разными платформами (Windows, Linux, Mac).
Недостатки текстовых файлов
- Нет строгой структуры (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. Типичные ошибки при работе с форматами
Если попытаться прочитать бинарный файл как текстовый, вы получите "кашу" из символов или вовсе ошибку. Аналогично, если открывать текстовый файл как бинарный и ожидать строгую структуру — будут проблемы.
Самая частая ошибка: несоответствие структуры данных и порядка чтения/записи. Например, сперва записали год, потом название, а читаете наоборот — получите не ту информацию. Всегда соблюдайте один и тот же порядок операций!
Очень часто программисты "подглядывают" в текстовый файл, проверяя логику сохранения и загрузки — именно для этого текстовые форматы и удобны в первые шаги. Бинарный же подходит для продвинутых сценариев, или когда нужно скрыть детали хранения от пользователя.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ