Книга: C# для профессионалов. Том II
Класс FileStream
Класс FileStream
Экземпляр FileStream
используется для чтения или записи данных файла. Чтобы создать FileStream
, необходимо иметь данные четырех видов:
? Файл для доступа.
? Режим, который указывает, как необходимо открыть файл. Например, собираетесь ли вы создать новый файл или открыть существующий файл, и, если открывается существующий файл, должна ли какая-либо операция записи интерпретироваться как перезапись содержимого файла или как добавление к файлу.
? Доступ, указывающий, как будет осуществляться доступ к файлу, будет ли выполняться чтение или запись в файл или и то и другое.
? Общий доступ. Другими словами, будет ли осуществляться исключительный доступ к файлу, или желательно, чтобы другие потоки могли одновременно получать доступ к этому файлу. Если так, то должны ли другие потоки иметь доступ для чтения файла, записи в него или для того и другого.
Первый из этих видов данных представлен обычно строкой, которая содержит полное имя пути доступа файла, и в этой главе будут рассматриваться только те конструкторы, которые требуют строку. Помимо этих конструкторов, существуют и некоторые другие, которые получают дескриптор файла Windows в стиле старого Windows API. Остальные три вида данных представлены тремя перечислениями .NET, называемыми соответственно FileMode
, FileAccess
и FileShare
. Значения этих перечислений должны быть понятны из названий.
Перечисление | Значения |
---|---|
FileMode (режим файла) |
Append (добавить), Create (создать), CreateNew (создать новый), Open (открыть), OpenOrCreate (открыть или создать), Truncate (обрезать) |
FileAccess (доступ к файлу) |
Read (чтение), ReadWrite (чтение-запись), Write (запись) |
FileShare (общий доступ к файлу) |
None (нет), Read (чтение), ReadWrite (чтение-запись), Write (запись) |
Отметим, что в случае FileMode
могут порождаться исключения, если запросить режим, который несогласован с существующим статусом файла. Append
, Open
и Truncate
будут порождать исключение, если файл еще не существует, a CreateNew
будет порождать исключение, если он существует. Create
и OpenOrCreate
будут удовлетворять любому сценарию, но Create
будет удалять любой существующий файл для замены его новым, вначале пустым файлом.
Существует большое число конструкторов для FileSream
. Три простейшие из них работают следующим образом:
// создает файл с доступом read-write и предоставляет другим потокам
// доступ на чтение
FileStream fs = new FileStream(@"C:C# ProjectsProjects.doc", FileMode.Create);
// как и выше, но мы получаем доступ к файлу только на запись
FileStream fs2 = new FileStream(@"C:C# ProjectsProjects2.doc", FileMode.Create, FileAccess.Write);
// как и выше, но другие потоки не имеют никакого доступа к файлу,
// пока fs3 открыт
FileStream fs3 = new FileStream(@"C:C# ProjectsProjects3.doc", FileMode.Create, FileAccess.Read, FileShare.None);
Из этого кода можно видеть, что эти перегружаемые версии конструкторов предоставляют значения по умолчанию FileAcces.ReadWrite
и FileShare.Read
для третьего и четвертого параметров. Также можно создать файловый поток из экземпляра FileInfo
:
FileInfo MyFile4 = new FileInfo(@"C:C# ProjectsProjects4.doc");
поставляет поток, предоставляющий доступ только для чтения к существующему файлу, в то время как FileInfo.OpenWrite() предоставляет доступ для чтения-записи.
FileStream fs4 = MyFile4.OpenRead();
FileInfo MyFile5 = new FileInfo(@"C:C# ProjectsProjects5.doc");
FileStream fs5 = MyFile5.OpenWrite();
FileInfo MyFile6 = new FileInfo(@"C:C# ProjectsProjects6.doc");
FileStream fs6 = MyFile6.Open(FileMode.Append, FileAccess.Read, FileShare.None);
FileInfo MyNewFile = new FileInfo(@"C:C# ProjectsProjectsNew.doc");
FileStream fs7 = MyNewFile.Create();
FileInfo.OpenRead()FileInfo.Open()
позволяет явно определить параметры режима, доступа и общего доступа.
Не забудьте, что по окончании работы поток необходимо закрыть:
fs.Close();
Закрытие потока освобождает связанные с ним ресурсы и позволяет другим приложениям настроить потоки на тот же самый файл. Для чтения и записи данных в поток FileStream
реализует ряд методов.
Метод ReadByte()
является простейшим способом чтения данных: он захватывает один байт из потока и преобразовывает результат в int, имеющее значение между 0 и 255. По достижении конца потока возвращается -1:
int NextByte = fs.ReadByte();
Если желательно прочитать несколько байтов за один раз, можно вызвать метод Read()
, который читает указанное число байтов в массиве. Read()
возвращает реально прочитанное число байтов, если это значение равно нулю, то это говорит о конце потока:
// считать 100 байтов int nBytes = 100;
byte [] ByteArray = new byte[nBytes];
int nBytesRead = fs.Read(ByteArray, 0, nBytes);
Второй параметр в методе Read()
— смещение, которое указывает операции Read
начать заполнение массива с элемента, отличного от первого.
Если требуется записать данные в файл, то существует два параллельных метода WriteByte()
и Write()
. WriteByte()
записывает один байт в поток:
byte Next Byte = 100; fs.WriteByte(NextByte);
, с другой стороны, записывает массив байтов:
Write()
// чтобы записать 100 байтов
int nBytes = 100;
byte [] ByteArray = new byte[nBytes];
// здесь массив заполняется значениями, которые надо записать
fs.Write(BуteArray, 0, nBytes);
Как и для метода Read(),
второй параметр позволяет начать записывать с некоторого места, отличного от начала массива. Оба метода WriteByte()
и Write()
возвращают void
.
Помимо этих методов FileStream
реализует также другие методы и свойства для выполнения задач учета, типа определения числа байтов в потоке, блокирования потока или очистки буфера. Эти методы обычно не требуются для базового чтения и записи, а если они потребуются, все детали находятся в документации MSDN.
- Класс FileStream и байтовый ввод-вывод в файл
- The FileStream Class
- Работа с FileStream
- Класс StreamReader
- Листинг 15.11. Код для загрузки файла с Web-сервера
- Вывод из строя коммутаторов
- Makefile Files
- Working with Files Using the File and FileInfo Classes
- The Stream Class
- MemoryStream
- The finally Statement
- 4.4. Ввод и вывод