Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
файлы лекция (вариант 1).pdf
Скачиваний:
22
Добавлен:
15.04.2015
Размер:
276.29 Кб
Скачать

Лекция 11. Файлы в С#

Основные понятия. Классы .NET для работы с файлами

Файл - именованная информация на внешнем носителе (на жестком или гибком магнитном диске).

Логически файл можно представить как конечное количество последовательных байтов, поэтому такие устройства, как дисплей, клавиатура и принтер, также можно рассматривать как частные случаи файлов.

Передача данных с внешнего устройства в оперативную память называется

чтением, или вводом, обратный процесс – записью, или выводом.

Чтение-запись в языке C# выполняется с помощью подсистемы ввода-вывода и классов библиотеки .NET. Рассмотрим обмен данными с файлами с помощью консоли, который реализуется с помощью потоков.

Поток (stream) – это любой перенос данных от источника к приемнику.

Потоки обеспечивают работу как со стандартными, так и с определенными пользователем типами данных. Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым производиться обмен (оперативная память, файл на диске, клавиатура и принтер).

Обмен с потоком для повышения скорости передачи данных производиться, как правило, через специальную область оперативной памяти – буфер. Буфер выделяется для каждого открытого файла.

При записи в файл вся информация сначала направляется в буфер и там накапливается до тех пор, пока весь буфер не заполниться. Только после этого и после специальной команды сброса происходит передача данных на внешнее устройство.

При чтении из файла данные вначале считываются в буфер, причем не столько, сколько запрашивается, а сколько помещается в буфер. Механизм буферизации позволяет более быстро и эффективно обмениваться информацией с внешними устройствами.

Для поддержки потоков библиотека .NET содержит иерархию классов, основная часть которой представлена на рисунке 1 Эти классы определены в пространстве имён System.IO.

Object

MarshalByRefObject FileSystemInfo DirectoryInfo

BinaryReader

 

 

 

 

 

FileInfo

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BinaryWriter

 

 

 

 

 

BufferedStream

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Directory

 

 

 

Stream

 

FileStream

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

File

 

 

 

 

 

MemoryStream

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StreamReader

 

 

 

 

TextReader

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StringReader

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StreamWriter

 

 

 

 

TextWriter

 

 

 

 

 

 

 

 

 

 

 

 

 

 

StringWriter

 

 

 

 

 

 

 

 

 

 

 

 

 

Рисунок 1: Основные классы пространства имен System.IO

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

 

Таблица 1: Основные классы пространства имен System.IO

 

 

 

Класс

 

Описание

BinaryReader

 

Чтение и запись значений простых

 

встроенных типов

 

 

BinaryWriter

 

(целочисленных, логических, строковых) во

 

внутренней форме представления

 

 

 

 

Временное хранение потока байтов

BufferedStream

 

(например, для последующего переноса в

 

 

постоянное хранилище)

Directory

 

Работа с каталогами или физическими

 

файлами: создание,

 

 

DirectoryInfo, File,

 

удаление, получение свойств. Возможности

 

классов File и

 

 

 

 

Directory реализованы в основном в виде

FileInfo

 

статических методов.Аналогичные классы

 

DirectoryInfo и FileInfo используют обычные

 

 

 

 

методы

 

 

 

FileStream

 

Произвольный (прямой) доступ к файлу,

 

представленному как поток байтов

 

 

MemoryStream

 

Произвольный доступ к потоку байтов в

 

оперативной памяти

 

 

StreamWriter

 

Чтение из файла и запись в файл текстовой

 

информации

 

 

StreamReader

 

( произвольный доступ не поддерживается )

 

 

 

StringReader

 

Работа с текстовой информацией в

 

оперативной памяти SrringReader

 

 

1Виды файлов

Информация, обрабатываемая фалами в С# может быть в виде:

двоичного представления данных(классы BinaryReader, BinaryWriter);

байтов (FileStream);

текста, то есть символов (StreamWriter, StreamReader).

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

Соответственно, различают текстовые, двоичные и байтовые файлы.

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

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

Методы форматированного ввода (ЧТЕНИЯ) значений арифметических типов, в С# не поддерживаются. Для преобразования из символьного в числовое представление используются методы класса Convert или метод Parse.

Форматированный вывод (ЗАПИСЬ) выполняется с помощью метода ToString, результаты выполнения которых передаются в методы текстовых файлов.

Алгоритм работы с файловыми потоками

Использование классов файловых потоков в программе предполагает следующие операции:

1.Создание потока и связывание его с физическим файлом.

2.Обмен информацией (чтение-запись).

3.Закрытие файла.

Каждый файл можно создавать разными способами и открывать в различных режимах (файлы можно открывать для чтения, только для записи или для чтения и записи).

Режимы доступа к файлу содержаться в переменной FileAccess, определенном в пространстве имен System.IO. Константы перечисления приведены в таблице 2.

 

 

Таблица 2: Значения перечисления FileAccess

 

 

 

Значение

 

Описание

Read

 

Открыть файл только для чтения

 

 

 

ReadWrite

 

Открыть файл для чтения и записи

 

 

 

Write

 

Открыть файл для записи

 

 

 

Возможные режимы открытия файла определены в переменной FileMode (таблица 3)

 

 

Таблица 3: Значения перечисления FileMode

 

 

 

Значение

 

Описание

 

Открыть файл, если он существует, и установить текущий

Append

указатель в конец файла. Если файл не существует, создать

 

новый файл

Create

Создать новый файл. Если в каталоге уже существует файл с

таким же именем, он будет стерт

 

CreateNew

Создать новый файл. Если в каталоге уже существует файл с

таким же именем, возникает исключение IOException

 

Open

Открыть существующий файл

OpenOrCreate

Открыть файл, если он существует. Если нет создать файл с

таким именем

 

Truncate

Открыть существующий файл. После открытия он должен

быть обрезан до нулевой длины

 

Режим FileMode.Append можно использовать только совместно с доступом типа FileAccess.Write, то есть для файлов, открываемых для записи.

2Байтовые файлы (потоки)

Ввод-вывод в файл на уровне байтов выполняется с помощью класса FileStream, основные элементы которого представлены в таблице 4.

 

Таблица 4: Методы и свойства класса Stream

 

 

Элемент

Описание

BeginRead,

Начать асинхронный ввод или вывод

BeginWrite

 

CanRead,

Свойства, определяющие, какие операции поддерживает

 

CanSeek,

поток: чтение, прямой доступ и/или запись

 

CanWrite

 

 

 

Close

Закрыть текущий поток и освободить связанные с ним

ресурсы (сокеты, указатели на файлы)

 

EndRead,

Ожидать завершения асинхронного ввода;

 

 

EndWrite

Закончить асинхронный вывод

 

Записать данные из буфера в связанный с потоком источник

Flush

данных и очистить буфер. Если для данного потока буфер не

 

используется, то этот метод ничего не делает

Length

Возвратить длину потока в байтах

 

 

Position

Возвратить текущую позицию в потоке

 

 

Read

Считать последовательность байтов (или один байт) из

текущего потока

 

ReadByte

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

байтов

 

 

 

Seek

Установить текущий указатель потока на заданную позицию

SetLength

Установить длину текущего потока

Write

Записать последовательность байтов (или один байт) в

текущий поток

 

WriteByte

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

байтов

 

Байтовый поток класс FileStream реализует эти элементы для работы с дисковыми файлами. Для определения режимов работы с файлом используются стандартные перечисления

FileMode, FileAccess.

Пример работы с байтовым файлом

using System;

using System.Collections.Generic; using System.Linq;

using System.Text; using System.IO;

namespace file_app

{

class Program

{

static void Main(string[] args)

{

Console.Title = "Приложение 1";

//создание файловой переменной и связывание с байтовым потоком - //файлом на диске с именем est.txt

//файл создается для чтения и записи

FileStream f = new FileStream("est.txt",FileMode.Create, FileAccess.ReadWrite);

f.WriteByte(100); //в начало файла записывается число 100 byte[] x = new byte[10];

for (byte i = 0; i < 10; ++i)

{

x[i] = (byte)(10 - i);

f.WriteByte(i); // записывается 10 чисел от 0 до 9

}

f.Write(x, 0, 5); //записывается 5 элементов массива byte[] y = new byte[20];

f.Seek(0, SeekOrigin.Begin); //текущий указатель – на начало

f.Read(y, 0, 20);

//чтение из

файла в массив

foreach (byte elem in y) Console.Write("

" + elem);

Console.WriteLine();

f.Seek(5, SeekOrigin.Begin); //текущий указатель – на 5-ый элемент

int a = f.ReadByte();

//чтение 5-го элемента

Console.WriteLine(a);

 

a = f.ReadByte();

//чтение 6-го элемента

Console.WriteLine(a);

 

Console.WriteLine("Текущая позиция в потоке " + f.Position); Console.ReadKey();

f.Close();

}

}

}

Результат работы программы:

Рисунок 2:

Текущая позиция в потоке первоначально устанавливается на начало файла (для любого режима открытия, кроме Append) и сдвигается на одну позицию при записи каждого байта.

Для установки желаемой позиции чтения используется метод Seek, имеющий два параметра: первый задает смещение в байтах относительно точки отсчета, задаваемой вторым. Точки отсчёта задаются константами перечисления SeekOrigin: начало файла – Begin, текущая позиция – Current и конец файла – End.

В данном примере файл создавался в текущем каталоге. Можно указать и полный путь к файлу, при этом удобнее использовать дословные литералы, например

FileStream f=new FileStream (@”D:\C#\test.txt”, FileMode.Create, FileAccess.ReadWrite);

В дословных литералах не требуется дублировать обратную косую черту.