Работа с файлами в C#: FileStream, StreamReader, StreamWriter и File API
Файлы и потоки
Файл — данные на диске с именем и путём. При открытии для чтения/записи становится потоком (stream) — последовательностью байтов. Два основных направления:
- Input stream — чтение (FileStream, StreamReader, BinaryReader)
- Output stream — запись (FileStream, StreamWriter, BinaryWriter)
Классы System.IO
| Класс | Назначение |
|---|---|
File | Статические методы для манипуляции файлами (создание, удаление, копирование, перемещение, открытие) |
FileInfo | Экземплярный аналог File, больше контроля |
Directory / DirectoryInfo | Работа с каталогами |
DriveInfo | Информация о дисках |
FileStream | Низкоуровневый байтовый доступ к файлу (чтение/запись байтов) |
StreamReader / StreamWriter | Текстовый ввод/вывод (кодировки, строки) |
BinaryReader / BinaryWriter | Бинарный ввод/вывод примитивных типов |
MemoryStream | Поток в памяти (byte[]) |
BufferedStream | Буферизация другого потока |
Path | Утилиты для путей (Combine, GetFileName, GetExtension и др.) |
StringReader / StringWriter | Чтение/запись из/в строку |
FileStream — байтовый доступ
var fs = new FileStream("test.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
// Запись байтов
for (int i = 1; i <= 20; i++)
fs.WriteByte((byte)i);
fs.Position = 0; // сброс в начало
// Чтение байтов
for (int i = 0; i <= 20; i++)
Console.Write(fs.ReadByte() + " "); // -1 в конце
fs.Close(); // или using
FileMode (как открывать)
CreateNew— новый файл, исключение если существуетCreate— новый или перезаписать существующийOpen— существующий, исключение если нетOpenOrCreate— открыть если есть, иначе создатьTruncate— открыть существующий и обнулить размерAppend— открыть и перейти в конец (или создать)
FileAccess
Read,Write,ReadWrite
FileShare
None,Read,Write,ReadWrite,Delete,Inheritable
Текстовые файлы: StreamReader / StreamWriter
// Запись
using (var writer = new StreamWriter("log.txt", append: true, Encoding.UTF8))
{
writer.WriteLine("Строка 1");
writer.WriteLine("Строка 2");
writer.Write("Без новой строки");
}
// Чтение всей строки
using (var reader = new StreamReader("log.txt", Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
Console.WriteLine(line);
}
// Чтение всего файла сразу (маленькие файлы)
string allText = File.ReadAllText("log.txt", Encoding.UTF8);
string[] lines = File.ReadAllLines("log.txt", Encoding.UTF8);
Бинарные файлы: BinaryReader / BinaryWriter
// Запись
using (var bw = new BinaryWriter(File.Open("data.bin", FileMode.Create)))
{
bw.Write(42); // int
bw.Write(3.14); // double
bw.Write("Hello"); // string (length-prefixed)
bw.Write(true); // bool
}
// Чтение (в ТОМ ЖЕ ПОРЯДКЕ!)
using (var br = new BinaryReader(File.OpenRead("data.bin")))
{
int i = br.ReadInt32();
double d = br.ReadDouble();
string s = br.ReadString();
bool b = br.ReadBoolean();
}
Современные удобные API (File, FileInfo)
// File — статические удобные методы
File.WriteAllText("a.txt", "content");
File.WriteAllLines("b.txt", new[] { "line1", "line2" });
File.AppendAllText("a.txt", "\nappended");
byte[] bytes = File.ReadAllBytes("data.bin");
string text = File.ReadAllText("a.txt");
string[] lines = File.ReadAllLines("a.txt");
// FileInfo — больше контроля
var fi = new FileInfo("data.txt");
Console.WriteLine(fi.Length);
Console.WriteLine(fi.CreationTime);
fi.CopyTo("backup.txt", overwrite: true);
fi.MoveTo("newname.txt");
fi.Delete();
// Асинхронные методы (.NET Core / .NET 5+)
await File.WriteAllTextAsync("async.txt", "content");
string text = await File.ReadAllTextAsync("async.txt");
Работа с путями (Path)
string path = Path.Combine("C:", "Users", "Name", "file.txt"); // C:\Users\Name\file.txt
string dir = Path.GetDirectoryName(path);
string file = Path.GetFileName(path);
string ext = Path.GetExtension(path);
string name = Path.GetFileNameWithoutExtension(path);
string full = Path.GetFullPath("relative/path.txt");
string temp = Path.GetTempFileName(); // уникальный временный файл
string tempDir = Path.GetTempPath();
Лучшие практики
- Всегда используйте
using(илиusing var) для автоматического закрытия/утилизации - Указывайте кодировку явно (
Encoding.UTF8) — избегайте проблем с кириллицей - Для больших файлов — потоковое чтение (
StreamReader.ReadLine), неReadAllText - Используйте
Path.Combineвместо конкатенации строк для путей - Асинхронные методы (
Asyncсуффикс) для UI/ASP.NET — не блокируют поток - Обрабатывайте
IOException,UnauthorizedAccessException,FileNotFoundException
Язык C
- Титан: ключевые свойства, применения и промышленное использование
- Кастаньеты: история, мастерство и исполнение
- Олово: от бронзового века к современной промышленности — применение, производство и будущее
- Ввод-вывод в C: scanf() и printf() — подробное руководство
- Работа с файлами в C: мастерство ввода-вывода с fopen, fprintf, fread и fseek
- Работа с файлами в Python: открытие, чтение, запись и управление
- Освоение ввода-вывода файлов в C: создание, открытие и управление файлами
- Заголовочные файлы в C: типы, подключение и лучшие практики
- Ввод-вывод файлов в Python: полное руководство по операциям I/O
- Напильники: виды, конструкция, правильная работа и техника безопасности