Flush Записать данные из буфера в связанный с потоком источник данных и очистить
буфер. Если для данного потока буфер не используется, то этот метод ничего не
делает
Length Возвратить длину потока в байтах
Position Возвратить текущую позицию в потоке
Read, Считать последовательность байтов (или один байт) из текущего потока
ReadByte и переместить указатель в потоке на количество считанных байтов
Seek Установить текущий указатель потока на заданную позицию
SetLength Установить длину текущего потока
Write, Записать последовательность байтов (или один байт) в текущий поток
WriteByte и переместить указатель в потоке на количество записанных байтов
Класс FileStream реализует эти элементы для работы с дисковыми файлами. Для определения режимов работы с файлом используются стандартные перечисления FileMode, FileAccess и FileShare. Значения этих перечислений приведены в табл. 11.2—11.4. В листинге 11.1 представлен пример работы с файлом. В примере демонстрируются чтение и запись одного байта и массива байтов, а также позиционирование в потоке.
|
|
Листинг 11.1. Пример использования потока байтов
using System;
using System.IO;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
FileStream f = new FileStream("test.txt", FileMode.Create,
FileAccess.ReadWrite);
f.WriteByte(100); //в начало файла записывается число 100
byte[] x = new byte[10];
for (byte i = 0; l < 10; ++i)
{
x[i] = (byte)(10 - i);
f.WriteByte(i); // записывается 10 чисел от 0 до 9
}
f.Write(x, 0, 5); // записывается 5 элементов массива
byte[] у = new byte[20];
f.Seek(0, SeekOrigin.Begin); // текущий указатель - на начало
f.Read(у, 0, 20); // чтение из файла в массив
foreach (byte elem in у)
Console.Write(" " + elem);
Console.WriteLine();
f.Seek(5.SeekOngin.Begin); //текущий указатель на 5-й елемент
int a = f.ReadByte(); // чтение 5-го элемента
Console.WriteLine(a);
а = f.ReadByte(); // чтение 6-го элемента
Console.WriteLine(a);
Console.WriteLine("Текущая позиция в потоке" + f.Position);
f.Close();
}
}
}
Результат работы программы:
100 0123456789 10 98760000
Текущая позиция в потоке 7
Текущая позиция в потоке первоначально устанавливается на начало файла (для любого режима открытия, кроме Append) и сдвигается на одну позицию при записи каждого байта.
Для установки желаемой позиции чтения используется метод Seek, имеющий два параметра: первый задает смещение в байтах относительно точки отсчета, задаваемой вторым. Точки отсчета задаются константами перечисления SeekOrigin: начало файла — Begin, текущая позиция — Current и конец файла — End.
В данном примере файл создавался в текущем каталоге. Можно указать и полный путь к файлу, при этом удобнее использовать дословные литералы, речь о которых шла в разделе «Литералы» (см. с. 30), например:
FileStream f = new FileStream(@"D:\C#\test.txt", FileMode.Create, FileAccess.ReadWrite);
В дословных литералах не требуется дублировать обратную косую черту.
|
|
Операции но открытию файлов могут завершиться неудачно, например, при ошибке в имени существующего файла или при отсутствии свободного места на диске, поэтому рекомендуется всегда контролировать результаты этих операций. В случае непредвиденных ситуаций среда выполнения генерирует различные исключения, обработку которых следует предусмотреть в программе, например:
□ FileNotFoundException, если файла с указанным именем в указанном каталоге
не существует;
□ DirectoryNotFoundException, если не существует указанный каталог;
□ ArgumentException, если неверно задан режим открытия файла;
□ IOException, если файл не открывается из-за ошибок ввода-вывода.
Возможны и другие исключительные ситуации.
Удобно обрабатывать наиболее вероятные ошибки раздельно, чтобы предоставить пользователю программы в выводимом сообщении наиболее точную информацию. В приведенном далее примере отдельно перехватывается ошибка в имени файла, а затем обрабатываются все остальные возможные ошибки:
try
{
FileStream f = new FileStream(@"d:\C#\test.tx", FileMode.Open,
FileAccess.Read);
// действия с файлом f.Close(); }
catch(FileNotFoundException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Проверьте правильность имени файла!"):
return;
}
catch(Exception e)
{
Console.WriteLine("Error: " + e.Message);
return;
}
При закрытии файла освобождаются все связанные с ним ресурсы, например, для файла, открытого для записи, в файл выгружается содержимое буфера. Поэтому рекомендуется всегда закрывать файлы после окончания работы, в особенности файлы, открытые для записи. Если буфер требуется выгрузить, не закрывая файл, используется метод Flush.