Ватсон Карли
Шрифт:
Существует большое число конструкторов для
FileSream
. Три простейшие из них работают следующим образом: // создает файл с доступом read-write и предоставляет другим потокам
// доступ на чтение
FileStream fs = new FileStream(@"C:\C# Projects\Projects.doc", FileMode.Create);
// как и выше, но мы получаем доступ к файлу только на запись
FileStream fs2 = new FileStream(@"C:\C# Projects\Projects2.doc", FileMode.Create, FileAccess.Write);
// как и выше, но другие потоки не имеют никакого доступа к файлу,
// пока fs3 открыт
FileStream fs3 = new FileStream(@"C:\C# Projects\Projects3.doc", FileMode.Create, FileAccess.Read, FileShare.None);
Из этого кода можно видеть, что эти перегружаемые версии конструкторов предоставляют значения по умолчанию
FileAcces.ReadWrite
и FileShare.Read
для третьего и четвертого параметров. Также можно создать файловый поток из экземпляра FileInfo
: FileInfo MyFile4 = new FileInfo(@"C:\C# Projects\Projects4.doc");
FileStream fs4 = MyFile4.OpenRead;
FileInfo MyFile5 = new FileInfo(@"C:\C# Projects\Projects5.doc");
FileStream fs5 = MyFile5.OpenWrite;
FileInfo MyFile6 = new FileInfo(@"C:\C# Projects\Projects6.doc");
FileStream fs6 = MyFile6.Open(FileMode.Append, FileAccess.Read, FileShare.None);
FileInfo MyNewFile = new FileInfo(@"C:\C# Projects\ProjectsNew.doc");
FileStream fs7 = MyNewFile.Create;
FileInfo.OpenRead
поставляет поток, предоставляющий доступ только для чтения к существующему файлу, в то время как FileInfo.OpenWrite предоставляет доступ для чтения-записи. 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
напишем пример BinaryFileReader
, который считывает и выводит любой файл. Он создается в Visual Studio.NET как оконное приложение. Добавляем один пункт меню, который выводит стандартный диалог OpenFileDialog
, запрашивающий файл для чтения, а затем выводит файл. Так как мы читаем двоичные файлы, нам необходимо иметь возможность выводить непечатные символы. Делаем это, выводя каждый байт файла отдельно, по 16 байтов в каждой строке многострочного текстового поля. Если байт представляет печатный символ ASCII, выводится этот символ, иначе выводится значение байта в шестнадцатеричном формате. В любом случае, мы дополняем выводимый текст пробелами, так что каждый выводимый 'байт' занимает четыре столбца, чтобы байты аккуратно выровнялись друг под другом.