В этой статье речь пойдет о
чтении/записи данных в файл, буфер или в память при помощи трех классов,
образованых от абстрактного класс System.IO.Stream. Мы рассмотрим
классы FileStream, MemoryStream, BufferedStream.
Классы, производные от Stream(поток),
предназначенны для работы с двоичными данными и могут искать какую-то
часть данных в потоке. Сам по себе, базовый класс уже имеет некоторые
методы и свойства, который унаследованы в следующих классах. Вот список и
предназначение этих методов и свойств.
CanRead |
Определяет, будет ли данный поток поддерживать чтение |
CanSeek |
Определяет, будет ли данный поток поддерживать поиск |
CanWrite |
И соответственно, будет ли поток поддерживать запись |
Close() |
Закрывает текущий поток и освобождает ресурсы |
Flush() |
Записывает все данные из буфера в соответствующий источник данных. Освобождает буфер |
Length |
Возвращает длину потока в байтах |
Position |
Определяет указатель на позицию в потоке |
Read() |
Читает последовательность байт |
ReadByte() |
Читает один байт |
Seek() |
Устанавливает указатель на местонахождение в текущем потоке |
SetLendth() |
Устанавливает длину текущего потока |
Write() |
Записывает последовательность байт |
WriteByte() |
Записывает один байт |
Перейдем к первому классу, унаследовавшему эти элементы
Класс FileStream
Этот класс предназначен для работы с файлами(их создание, чтение, запись). Вот пример его использования:
FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
Здесь переменная filename указывает
на имя файла, а остальные параметры указывают на ограничения и
допустимые действия над ним. Рассмотрим их поподробнее.
Перечесление FileMode:
FileMode.Append |
Открыть
файл(переданный первым параметром) и установить указатель на конец
файла(то есть для дописываения в него данных. Можно использовать только с
FileAccess.Write, иначе будет сгенерировано исключение System.ArgumentException. Если файл отсутствует, то он создается автоматически и открывается для записи. |
FileMode.Create |
Создать новый файл. Если файл уже существует, то перезаписать его. |
FileMode.CreateNew |
Отличается от предыдущего тем, что если файл уже существует, то будет сгенерировано исключение |
FileMode.Open |
Открыть файл и установить указатель на начало. Если файл не существует, будет сгенерировано исключение System.IO.FileNotFoundException |
FileMode.OpenOrCreate |
Отличается от предыдущего тем, что при отсутствии файла, его создает. |
FileMode.Truncate |
Открывает существующий файл и
обрезает его длину до 0 байт. Попытка прочитать файл с указанием такого
перечисления приведет к исключению |
Перечисление FileAccess:
FileAccess.Read |
Файл открывается исключительно для чтения |
FileAccess.Write |
Файл открывается исключительно для записи |
FileAccess.ReadWrite |
Это комбо-вариант двух предыдущих |
Есть также перечисление FileShare, но
оно для нас сейчас не является столь важным. Оно нужно для
синхронизации записи или чтения с другими потоками.
Вот код, демонстрирующий простую запись в файл и чтение из него в консоль
FileStream stream = new FileStream("test.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite);
for(int i = 0: i < 256; i++)
{
myFStream.WriteByte((byte)i);
}
// Переставляем внутренний указатель на начало
myFStream.Position = 0;
// Считываем байты из файла *.dat
for(int i = 0; i < 256; i++)
(
Console.Write(myFStream.ReadByte());
}
myFStream.Close();
Класс MemoryStream
Этот класс не особо
отличается от предыдущего, нами рассмотренного, за исключением того, что
он работает(записывает и читает) не с файлом, а с оперативной памятью.
Ниже перечисленны наиболее важные его члены:
Capacity |
Это свойство позволяет получить или установить кол-во байтов выделенных под этот поток |
GetBuffer() |
Возвращает массив байтов при помощи которых был создан поток |
ToArray() |
Записывает все содержимое потока в массив байтов не зависимо от свойства Position |
WriteTo() |
Записывает все содержимое объекта(MemoryStream) в другой обьект класса, производного от Stream(например в FileStream) |
Вот пример кода осуществляющего запись в файл из MemoryStream через FileStream:
FileStream dumpFile = new FIleStream("Dump.dat", FleMode.Create, FileAccess.ReadWrlte);
myMemStream.WriteTo(dumpFile);
myMemStream есть объект класса MemoryStream.
Класс BufferedStream
И завершает нашу тройку
класс BufferedStream. Этот класс нужен для организации временного
хранилища данных, чтобы потом передать их в постоянное хранилище.
Казалось бы, для чего это нужно, разве не проще просто записать
некоторые данные через FileStream.Write()? Конечно можно, но если нам
нужна производительность, то лучше использовать буфер, так как при
многократном вызове FileStream.Write() нам приходиться много раз
обращаться к диску, что существенно замедляет работу нащей программы.
Вот пример использования BufferedStream
// Создаем объект BufferedStream. подключенный к уже имеющемуся объекту FileStream
BufferedStream rnyFileBuffer = new BufferedStream(dumpFile);
// Добавляем в BufferedStream несколько байтов
byte[] str = {127, 0x77, 0x4, 0x0, 0x0, 0x16};
myFileBuffer.Write(str, 0, str.Length);
// А теперь записываем все содержимое BufferedStream в файл
myFlleBuffer.Close();
Ну вот впринципе и все что. Успехов вам в программировании.