OOP Course
Сьогодні

Підрозділ 18.3

Stream та FileStream. Потоковий доступ до файлів

18.3. Stream та FileStream. Потоковий доступ до файлів Усі класи File.WriteAllText , File.ReadAllBytes — це зручні обгортки над нижчим рівнем абстракції: потоками streams . Потік — це абстракція послідовного до

18.3. Stream та FileStream. Потоковий доступ до файлів

Усі класи File.WriteAllText, File.ReadAllBytes — це зручні обгортки над нижчим рівнем абстракції: потоками (streams). Потік — це абстракція послідовного доступу до даних, де читання або запис відбуваються по шматках (chunk by chunk), а не завантаженням усього ресурсу у пам'ять одразу. Розуміння потоків є фундаментом для роботи не лише з файлами, а й з мережевими з'єднаннями, ZIP-архівами, HTTP-відповідями, шифруванням — будь-яким I/O у .NET.

Абстрактний клас Stream визначає єдиний контракт для всіх видів потоків. FileStream — одна з конкретних реалізацій, що забезпечує потоковий доступ до файлів на диску.

Ієрархія класів Stream у .NET

Абстрактний клас Stream

Stream (простір імен System.IO) визначає мінімальний набір можливостей, якими може володіти або не володіти потік:

Stream визначає три типи операцій: читання (Read, ReadByte), запис (Write, WriteByte, Flush) і позиціонування (Seek, Position). Не всі потоки підтримують усі операції — мережевий потік NetworkStream не підтримує Seek (CanSeek == false), потік лише для читання не підтримує Write. Перевіряйте CanRead/CanWrite/CanSeek перед використанням.

Клас FileStream

FileStream — реалізація Stream для файлів на диску. Він підтримує всі три операції: читання, запис і позиціонування (CanSeek == true).

Відкриття файлу: FileMode та FileAccess

FileMode визначає, що відбувається при відкритті:

FileMode Якщо файл існує Якщо файл не існує
Create Обрізає до нуля Створює новий
CreateNew Кидає IOException Створює новий
Open Відкриває Кидає FileNotFoundException
OpenOrCreate Відкриває Створює новий
Append Відкриває, позиція в кінці Створює новий
Truncate Обрізає до нуля Кидає FileNotFoundException

Буферизований запис та Flush

Flush() гарантує, що буферизовані дані записані на фізичний диск. Для критичних даних (медичні журнали, транзакції) — викликайте Flush() після кожного запису. При звичайних ситуаціях using / Dispose автоматично виконає Flush і Close.

Паралельний доступ: FileShare

FileShare визначає, що дозволяється іншим процесам (або потокам) робити з файлом, поки він відкритий у вас:

FileShare Опис
None Виключний доступ — ніхто інший не може відкрити файл
Read Інші можуть відкривати для читання
Write Інші можуть відкривати для запису
ReadWrite Інші можуть відкривати для читання і запису
Delete Інші можуть видаляти файл

Читання та запис по шматках — ефективна обробка великих файлів

Ключова перевага потокового доступу — обробка файлів будь-якого розміру при константному використанні пам'яті:

Stream.CopyTo(Stream destination, int bufferSize) — вбудований метод для копіювання між будь-якими потоками: з файлу у файл, з файлу у мережу, з HTTP-відповіді у файл. Внутрішньо він теж читає по шматках вказаного розміру.

Seekable потік: довільний доступ до даних

Файлові потоки (CanSeek == true) підтримують довільний доступ — стрибок до будь-якої позиції за O(1). Це основа для баз даних фіксованих записів, індексних структур і форматів з заголовками.

MemoryStream — потік у пам'яті

MemoryStream реалізує Stream над масивом байтів у пам'яті. Не звертається до диску, але реалізує той самий інтерфейс. Корисний для тестування (замість реальних файлів), серіалізації у пам'яті та конвеєрів обробки:

leaveOpen: true у конструкторі StreamWriter — важливий параметр: без нього StreamWriter.Dispose() закриє і MemoryStream, і ми не зможемо прочитати дані після using-блоку.

Практичний сценарій: журнал медичних подій з FileStream

FileMode та FileAccess — параметри відкриття файлу

Розроблено Tomka Yurii · © 2026 ·