Чтение и запись файла.
Для чтения файла создадим приложение Windows Forms, включающее обычное текстовое поле, список, 2 кнопки «Прочитать» и «Записать», с подключением с помощью оператора using пространства имен System.IO.
Пользователь вводит путь определенного файла в текстовом поле и щелкает на кнопке «Прочитать». С этого момента приложение читает указанный файл и отображает его содержимое в списке.
Так как нам понадобится работать с содержимым файла строка за строкой, то можно воспользоваться методом кeadAllLines, поскольку он как раз и позволяет это делать.
string [] a;
a=File.ReadAllLines(textBox1.Text);
int i;
i = a.Length;
for (int k=0;k<i;k++)
listBox1.Items.Add(a[k]);
Другие варианты чтения и работы с файлами предусматривают использование методов ReadAllBytes и ReadAll. Метод ReadAllBytes позволяет открывать двоичные файлы и читать их содержимое в байтовый массив. Метод ReadAll, возвращает содержимое файла в виде одного экземпляра строки.
Для записи файла воспользуемся тем же приложением Windows Forms, но на этот раз запишем содержимое списка в файл, воспользовавшись кнопкой «Записать».
|
|
int i;
i = listBox1.Items.Count;
string[] a =new string[i];
for (int k = 0; k < i; k++)
a[k]=listBox1.Items[k].ToString();
File.WriteAllLines(textBox1.Text,a);
Потоки
Идея потока существует очень долгое время. Поток (stream) — это объект, используемый для передачи данных. Данные могут передаваться в одном из двух направлений:
Если данные передаются в программу из некоторого внешнего источника, говорят о чтении потока.
Если данные передаются из программы в некоторое внешнее местоположение, это называют записью в поток.
Очень часто внешним источником и местом назначения является файл, хотя это не обязательно. Другие возможности включают:
Чтение и запись данных в сети с использованием некоторого сетевого протокола, когда необходимо получить данные, отправленные другим компьютером, или отправить их ему.
Чтения и запись в именованном канале.
Чтение и запись в области памяти.
Microsoft поставляет ряд базовых классов.NET для чтения и записи в память. Не существует базовых классов для чтения и записи именованных каналов, но есть обобщенный потоковый класс System.IO.Stream, от которого можно унаследовать такой класс. Поток не делает никаких предположений относительно природы внешнего источника данных.
Внешним источником может быть даже переменная из вашего собственного кода. Технология применения потоков для передачи данных между переменными может оказаться полезной для преобразования типов данных. Преимущество использования отдельного объекта для передачи данных состоит в том, что за счет отделения концепции передачи данных от конкретного источника гораздо легче заменять источники. Сами потоковые объекты содержат множество обобщенного кода, предназначенного для перемещения данных между внешними источниками и переменными вашего кода, и за счет того, что этот код отделен от любой концепции источника, и его гораздо легче повторно использовать (через наследование) в различных ситуациях.
|
|
Поскольку мы рассматриваем чтение и запись файлов, то более всего нас интересуют следующие классы: FileStream — класс предназначен для чтения и записи двоичных данных в двоичных файлах. StreamReader и StreamWriter — эти классы предназначены специально для чтения и записи текстовых файлов.
Могут быть полезными также классы BinaryReader и BinaryWriter. Эти классы сами по себе не реализуют потоков, но они могут служить оболочками для потоковых объектов. BinaryReader и BinaryWriter обеспечивают дополнительное форматирование двоичных данных, что позволяет непосредственно читать и писать содержимое переменных С# в потоке. Эти классы можно представлять в виде посредников, находящихся между потоком и вашим кодом и обеспечивающих дополнительное форматирование.
Разница между применением этих классов и прямым использованием лежащих в основе потоковых объектов состоит в том, что базовые потоки работают с байтами. Например, предположим, что в качестве части процесса сохранения некоторого документа вы хотите записать содержимое переменной типа long в бинарный файл.
Каждая переменная типа long занимает 8 байт, и если вы используете обычный двоичный поток, то должны будете явно записывать каждые из этих 8 байт в поток (а поскольку поток направлен в файл, значит, записывать в файл). Соответствующий метод BinaryReader.Read () извлечет 8 байт из потока и восстановит их в переменную типа long.
Буферизованные потоки
По причинам, связанным с производительностью, когда вы читаете или пишете файл, вывод буферизуется. Это значит, что если ваша программа запрашивает следующие 2 байта из файлового потока, то поток передает запрос Windows, после чего Windows не обременяет себя подключением к файловой системе, нахождением и чтением файла на диске только для того, чтобы получить 2 байта. Вместо этого Windows извлечет большой блок файла в один прием и сохранит его в области памяти, называемой буфером. Последующие запросы данных потока будут удовлетворены за счет буфера — до тех пор, пока буфер не кончится, и тогда Windows извлечет очередной блок данных из файла. Запись в файлы работает аналогичным образом. Для файлов это делается операционной системой автоматически, но у вас может быть потоковый класс, работающий с небуферизованным устройством. В этом случае можно наследовать класс от BufferedStream, который сам реализует буфер. Экземпляр FileStream используется для чтения и записи данных в файл. Для того чтобы сконструировать объект FileStream, необходима следующая информация:
Файл, к которому нужно получить доступ.
Режим, который указывает, как нужно открыть файл. Например, намерены ли вы создать новый файл или же открыть существующий? И если вы открываете существующий файл, должны ли операции записи интерпретироваться как перезапись старого содержимого файла или же как добавление к нему новых данных?
Доступ, указывающий, как вы хотите обращаться к файлу. Например, нужно файл читать, писать или же делать и то и другое?
Разделение доступа, что определяет, нужен ли вам исключительный доступ к файлу. Или же вы хотите дать возможность другим потокам обращаться к файлу одновременно? Если так, должны ли другие потоки иметь доступ к этому файлу на чтение, на запись или на то и другое?