Чтение онлайн

на главную - закладки

Жанры

C# для профессионалов. Том II

Ватсон Карли

Шрифт:

Потоки 

Идея потока существует уже очень давно. Поток является объектом, используемым для пересылки данных. Данные могут передаваться в одном или в двух направлениях:

□ Если данные передаются в программу из некоторого внешнего источника, то речь идет о чтении из потока.

□ Если данные передаются из программы в некоторый внешний источник, то речь идет о записи в поток.

Очень часто внешний источник является файлом, но не всегда. Другими вариантами могут быть:

□ Чтение или запись данных в сети с помощью некоторого сетевого протокола, куда посылают данные или получают с другого компьютера.

□ Чтение или запись через именованный канал.

□ Чтение или запись данных в области памяти.

Для

таких примеров Microsoft поставляет базовый класс .NET для записи в память и чтения из памяти
System.IO.MemoryStream
, в то время как
System.Net.Sockets.Networkstream
обрабатывает сетевые данные. Не существует базовых классов потока для записи в каналы или чтения из каналов, но существует базовый класс потока,
System.IO.Stream
, из которого можно создать, если понадобиться, производный класс. Поток не делает никаких предположений о природе внешнего источника данных.

Внешний источник иногда бывает даже переменной в коде приложения. Возможно, это звучит парадоксально, но техника использования потоков для передачи данных между переменными может оказаться полезным приемом для преобразования типов данных. Язык С использовал что-то подобное для преобразования между целыми типами данных и строками или для форматирования строк с помощью функции

sprintf
, а в C# два базовых класса .NET,
StringReader
и
StringWriter
, могут использоваться в таком контексте.

Преимущество применения отдельного объекта для передачи данных, вместо классов

FileInfo
и
DirectoryInfo
, состоит в том, что разделение концепции передачи данных и определенного источника данных облегчает замену источников данных. Сами объекты потоков содержат большой объем базового кода, имеющего отношение к переносу данных между внешними источниками и переменными в коде приложения, и сохраняя этот код отдельно от любой концепции определенного источника данных, мы облегчаем повторное применения этого кода (через наследование) в различных обстоятельствах. Например, упомянутые выше классы
StringReader
и
StringWriter
являются частью того же дерева наследования, что и два класса, используемых для чтения и записи текстовых файлов, —
StreamReader
и
StreamWriter
. Классы почти наверняка неявно задействуют значительный объем общего кода.

Реальная иерархия связанных с потоком классов в пространстве имен

System.IO
выглядит следующим образом:

Что касается чтения из файлов или записи в файлы, то мы будем связаны в основном со следующими классами:

□ 

FileStream
. Этот класс предназначен для чтения и записи двоичных данных в произвольный двоичный файл, однако при желании можно использовать его для чтения и записи в любой файл.

StreamReader
и
StreamWriter
. Эти классы специально предназначены для чтения и записи в текстовые файлы.

Упомянем также другие классы, которые могут оказаться полезными, хотя они и не будут представлены в приводимых примерах. Если вы хотите использовать эти классы, обратитесь к документации MSDN, чтобы получить подробности об их работе.

BinaryReader
и
BinaryWriter
. Эти классы в действительности сами не реализуют потоки, но они могут обеспечить оболочки вокруг других потоковых объектов.
BinaryReader
и
BinaryWriter
поддерживают дополнительное форматирование двоичных данных, что позволяет напрямую читать или записывать содержимое переменных C# в соответствующий поток. Проще всего считать, что
BinaryReader
и
BinaryWriter
находятся между потоком и кодом приложения, обеспечивая дополнительное форматирование:

Различие

между использованием этих классов и непосредственным использованием описанных ниже потоковых объектов состоит в том, что базовый поток работает с байтами. Например, пусть часть процесса сохранения некоторого документа состоит в записи содержимого переменной типа
long
в двоичный файл. Каждая переменная типа
long
занимает 8 байтов, если используется плоский обыкновенный двоичный поток, необходимо будет явно записывать каждые эти 8 байтов памяти. В коде C# это будет означать, что необходимо явно выполнять некоторые битовые операции для извлечения каждых 8 байтов из значения
long
. Используя экземпляр
BinaryWriter
, можно инкапсулировать всю операцию в перегруженный метод
BinaryWriter.Write
, который получает
long
в качестве параметра и который будет помещать эти 8 байтов в поток (и следовательно, если поток направлен в файл, то в файл). Соответствующий метод
BinaryReader.Read
будет извлекать 8 байтов из потока и восстанавливать значение
long
.

BufferedStream
. По соображениям производительности при чтении из файла или при записи в файл вывод буферизуется. Это означает, что если программа запрашивает следующие 2 байта файлового потока и поток передает запрос Windows, то Windows не станет соединяться с файловой системой и затем искать и считывать файл с диска, для того чтобы получить 2 байта. Вместо этого произойдет извлечение большого блока файла за один раз и сохранение этого блока в области памяти, называемой буфером. Последующие запросы данных из потока будут удовлетворяться из буфера, пока он не будет исчерпан, и тогда Windows извлечет другой блок данных из файла. Запись в файлы работает таким же образом. Для файлов это делается автоматически операционной системой, но возможен случай, когда придется написать потоковый класс для чтения из некоторого другого устройства, которое не буферизуется. В таком случае можно вывести этот класс из
BufferedStream
, который сам реализует буфер (
BufferedStream
не создан, однако, для ситуаций, когда приложение часто чередует операции чтения и записи данных).

Чтение и запись двоичных файлов

Чтение и запись двоичных файлов делается обычно с помощью класса

FileStream
.

Класс FileStream

Экземпляр

FileStream
используется для чтения или записи данных файла. Чтобы создать
FileStream
, необходимо иметь данные четырех видов:

Файл для доступа.

□ Режим, который указывает, как необходимо открыть файл. Например, собираетесь ли вы создать новый файл или открыть существующий файл, и, если открывается существующий файл, должна ли какая-либо операция записи интерпретироваться как перезапись содержимого файла или как добавление к файлу.

Доступ, указывающий, как будет осуществляться доступ к файлу, будет ли выполняться чтение или запись в файл или и то и другое.

□ Общий доступ. Другими словами, будет ли осуществляться исключительный доступ к файлу, или желательно, чтобы другие потоки могли одновременно получать доступ к этому файлу. Если так, то должны ли другие потоки иметь доступ для чтения файла, записи в него или для того и другого.

Первый из этих видов данных представлен обычно строкой, которая содержит полное имя пути доступа файла, и в этой главе будут рассматриваться только те конструкторы, которые требуют строку. Помимо этих конструкторов, существуют и некоторые другие, которые получают дескриптор файла Windows в стиле старого Windows API. Остальные три вида данных представлены тремя перечислениями .NET, называемыми соответственно

FileMode
,
FileAccess
и
FileShare
. Значения этих перечислений должны быть понятны из названий.

Поделиться:
Популярные книги

Скандальная свадьба

Данич Дина
1. Такие разные свадьбы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Скандальная свадьба

Последнее желание

Сапковский Анджей
1. Ведьмак
Фантастика:
фэнтези
9.43
рейтинг книги
Последнее желание

Правильный попаданец

Дашко Дмитрий Николаевич
1. Мент
Фантастика:
альтернативная история
5.75
рейтинг книги
Правильный попаданец

Купец V ранга

Вяч Павел
5. Купец
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Купец V ранга

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5

Лорд Системы

Токсик Саша
1. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
4.00
рейтинг книги
Лорд Системы

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

Граф

Ланцов Михаил Алексеевич
6. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Граф

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Старая дева

Брэйн Даниэль
2. Ваш выход, маэстро!
Фантастика:
фэнтези
5.00
рейтинг книги
Старая дева

Я тебя верну

Вечная Ольга
2. Сага о подсолнухах
Любовные романы:
современные любовные романы
эро литература
5.50
рейтинг книги
Я тебя верну

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи

Метка драконов. Княжеский отбор

Максименко Анастасия
Фантастика:
фэнтези
5.50
рейтинг книги
Метка драконов. Княжеский отбор