парадигмы-лек_1-мод_3.ppt
- Количество слайдов: 52
Средства ввода-вывода Файлы и потоки
Большинство операций ввода-вывода в. NET Framework реализованы в пространстве имен System. IO. В. NET Framework различаются файлы и потоки. Файл представляет собой поименованные данные, хранящиеся на диске; часто, кроме имени, указан и каталог. При открытии для чтения/записи файл становится потоком.
Что такое поток? Поток - это абстракция последовательности байтов. Поток может быть файлом, областью памяти, или сокетом TCP/IP. Потоки могут поддерживать три основные операции: чтение, запись и поиск. Чтение из потока - это перенос данных из потока в структуру данных, такую как например массив байтов. Запись в поток – это перенос данных из структуры данных в поток. Поиск – это изменение текущей позиции внутри потока. Не все потоки поддерживают все три операции, их поддержка зависит от вида резервного хранилища потока или базового источника. Сетевые потоки как правило поиск не поддерживают. Абстрактный класс Stream является базовым классом для всех потоков в FCL. О том поддерживает ли поток различные операции, можно узнать помощью свойств Can. Read, Can. Write и Can. Seek.
Средства ввода-вывода Пространство имен System. IO предоставляет типы, которые позволяют выполнять с файлами, каталогами различные действия, а также синхронное и асинхронное чтение и запись данных в потоки или файлы. Помимо типов позволяющих производить чтение и запись байтов в потоки и файлы предусмотрены типы для чтения и записи двоичных данных. На самом деле типы манипулирующие файлами и производящие чтение и запись не работают с файлами напрямую. Они используют набор функций и структур для работы с файлами предоставляемые операционной системой Windows. 4
Файлы и директории Для работы с файлами и директориями в FCL существует два набора классов с практически однинаковой функциональностью. Классы File. Info и Directory. Info предоставляют методы экземпляра для создания, копирования, удаления, перемещения файлов и для получения объекта File. Stream. Классы File и Directory предоставляют статические методы для создания, копирования, удаления, перемещения файлов и для получения объекта File. Stream. Методы этих классов используют в качестве параметров несколько перечислений. Перечисление File. Access позволяет установить доступ к файлу с правами чтения и записи. Перечисление File. Share позволяет установить уровень разрешенного доступа для уже используемого файла. Перечисление File. Mode позволяет установить что будет происходить в случае если файл уже существует.
Абстрактный класс File. System. Info public abstract class File. System. Info : Marshal. By. Ref. Object, ISerializable { public File. Attributes { get; set; } public Date. Time Creation. Time. Utc { get; set; } public abstract bool Exists { get; } public string Extension { get; } public virtual string Full. Name { get; } public Date. Time Last. Access. Time { get; set; } public Date. Time Last. Access. Time. Utc { get; set; } public Date. Time Last. Write. Time. Utc { get; set; } public abstract string Name { get; } } public abstract void Delete(); public void Refresh();
Класс Directory. Info public sealed class Directory. Info : File. System. Info { public void Create(); public Directory. Info Create. Subdirectory(string path); public Directory. Security Get. Access. Control(); public Directory. Info[] Get. Directories(); public File. Info[] Get. Files(); public File. System. Info[] Get. File. System. Infos(); public void Set. Access. Control(Directory. Security directory. Security); }
Методы класса Directory. Info §Метод Create создаёт поддиректорию. §Метод Create. Subdirectory создаёт одну или несколько поддиректорий по указанному пути. §Метод Get. Access. Control возвращает список управления доступом для директории. §Метод Get. Directories возвращает поддиректории текущей директории. §Метод Get. Files возвращает файлы в текущей директории. §Метод Get. Files. System. Infos возвращает файлы и дирктории в текущей директории. §Метод Set. Access. Control меняет список управления доступом для директории.
Создание директорий static void Main() { Console. Write. Line("***** Создание директорий с помощью Directory. Info ***** n"); Directory. Info dir = new Directory. Info(@"C: Windows"); dir. Create. Subdirectory("My. Foo"); dir. Create. Subdirectory(@"My. BarMy. Qaaz"); }
Создание директорий static void Main() { Console. Write. Line("***** Создание директорий с помощью Directory. Info ***** n"); Directory. Info dir = new Directory. Info(@"C: Windows"); Directory. Info subdir = dir. Create. Subdirectory("My. Foo"); Console. Write. Line("Создана директория: {0} ", subdir. Full. Name); subdir = dir. Create. Subdirectory(@"My. BarMy. Qaaz"); Console. Write. Line("Создана директория: {0} ", subdir. Full. Name); }
Перечисление File. Attributes Public enum File. Attributes { Read. Only, Hidden, System, Directory, Archive, Device, Normary, Temporary, Sparse. File, Reparse. Point, Compressed, Offline, Not. Content. Indexed, Encrypted }
Получение файлов в директории static void Main() { Console. Write. Line("***** Получение списка файлов в директории ***** n"); } Directory. Info dir = new Directory. Info(@"C: Windows"); File. Info[] bitmap. Files = dir. Get. Files("*. bmp"); Console. Write. Line("Найдено {0} файлов bmp в директории {1}", bitmap. Files. Length, dir. Full. Name ); foreach (File. Info f in bitmap. Files) { Console. Write. Line("Название файла: {0}", f. Name); Console. Write. Line("Размер файла: {0}", f. Length); Console. Write. Line("Создан: {0}", f. Creation. Time); Console. Write. Line("Атрибуты : {0}", f. Attributes); }
Класс File. Info public sealed class File. Info : File. System. Info { public File. Info Copy. To(string dest. File. Name); public File. Stream Create(); public File. Security Get. Access. Control(); public void Move. To(string dest. File. Name); public File. Stream Open(File. Mode mode, File. Access access, File. Share share); public File. Stream Open. Read(); public File. Stream Open. Write(); public void Set. Access. Control(File. Security file. Security); }
Методы класса File. Info §Метод Copy. To копирует файл. §Метод Create создаёт файл. §Метод Get. Access. Control возвращает список управления доступом для файла. §Метод Move. To перемещает (переименовывает) файл. §Метод Open открывает файл в заданном режиме, с заданным доступом и с заданным типом совместного доступа. §Метод Open. Write открывает файл для записи. §Метод Open. Read открывает файл для чтения. §Метод Set. Access. Control меняет список управления доступом для файла.
Абстрактный класс Stream public abstract class Stream : Marshal. By. Ref. Object, IDisposable { public virtual void Close(); public abstract void Flush(); public abstract int Read(byte[] buffer, int offset, int count); public virtual int Read. Byte(); public abstract long Seek(long offset, Seek. Origin origin); public abstract void Set. Length(long value); public abstract void Write(byte[] buffer, int offset, int count); public virtual void Write. Byte(byte value); } public public abstract abstract bool long Can. Read { get; } Can. Write { get; } Can. Seek { get; } Length { get; } Position { get; set; }
Класс File. Stream public abstract class Stream : Marshal. By. Ref. Object, IDisposable { public virtual void Close(); public override void Flush(); public override int Read(byte[] buffer, int offset, int count); public override int Read. Byte(); public override long Seek(long offset, Seek. Origin origin); public override void Set. Length( long value); public override void Write(byte[] buffer, int offset, int count); public override void Write. Byte(byte value); } public public override override bool long Can. Read { get; }; Can. Seek { get; }; Can. Write { get; }; Length { get; }; Position { get; set; };
Конструкторы File. Stream (выборочно) • File. Stream(string str. File. Name, File. Mode fm, File. Access fa) • File. Stream(string str. File. Name, File. Mode fm, File. Access fa, File. Share fs) • File. Stream(strlng str. File. Name, File. Mode fm, File. Access fa, File. Share fs, int i. Buffer. Size) • File. Stream(string str. File. Name, File. Mode fm, File. Access fa, File. Share fs, int i. Buffer. Size, bool b. Async)
Запись в файл static void Main() { Console. Write. Line("***** Запись в файл *****n"); File. Info f = new File. Info(@"C: Test. dat"); File. Stream fs = f. Create(); string msg ="Привет Мир!"; byte[] msg. Bytes = Encoding. Default. Get. Bytes(msg); fs. Write(msg. Bytes, 0, msg. Bytes. Length); fs. Close(); }
Чтение из файла static void Main() { Console. Write. Line("***** Чтение из файла *****n"); File. Info f = new File. Info(@"C: Test. dat"); File. Stream fs = f. Open(File. Mode. Open, File. Access. Read, File. Share. Read); byte[] msg. Bytes = new byte[22]; fs. Read(msg. Bytes, 0, msg. Bytes. Length); Console. Write. Line(Encoding. Default. Get. Strin g( msg. Bytes)); fs. Close(); }
класс File. Stream • Этот базовый класс используется для открытия, чтения, записи и закрытия файлов. File. Stream наследуется от абстрактного класса Stream, и множество его свойств и методов являются производными из этого класса. • Для открытия существующего файла или создания нового нужно создать объект класса File. Stream. который имеет пять конструкторов;
• File. Mode, File. Access, и File. Share — это перечисления, определенные в пространстве имен System. l. O. • File. Mode определяет, открывается ли существующий файл или создается новый, а также что делать, если открываемого файла не существует или, наоборот, создаваемый файл уже есть.
Перечисление File. Mode Create. New 1 Ошибка, если файл существует Create 2 Если файл существует, его содержимое удаляется Open 3 Ошибка, если файл не существует. Open. Or. Create 4 Если файл не существует, он создается. Truncate 5 Ошибка, если файл не существует; содержимое файла удаляется.
Append 6 Ошибка, если файл открывается на чтение; если файл не существует, он создается; указатель устанавливается на конец файла,
• Под ошибкой подразумевается то, что конструктор File. Stream вызывает исключение типа l. OException или File. Not. Found. Exception. • Если вы не укажете аргумент File. Access, файл открывается как для чтения, так и для записи. • Аргумент File. Access указывает режим доступа к файлу: чтение, запись или обе операции;
Перечисление File. Access Член Значение Описание Read 1 Write 2 Ошибка при использовании File. Mode. Create. New File. Mode. Create File. Mode. Truncate, или File. Mode. Append. Ошибка, если файл имеет атрибут «только для чтения» Read. Write 3 Ошибка при использовании File. Mode Append или файл имеет атрибут «только для чтения»
• Аргумент File. Access нельзя опустить только в одном случае: когда вы открываете файл с указанием File. Mode Append, конструктор не выполнится, если файл открывается для чтения. • Так как по умолчанию файлы открываются для чтения и записи, такой конструктор никогда не выполнится:
• new File. Stream(str. File. Name, File. Mode. Append) • Если вы хотите использовать File. Mode. Append, включите аргумент File. Access. Write. • new File. Stream(str. File. Name, File. Mode. Append, File. Access. Write) • Если вы не укажете аргумент File. Share, файл открывается для монопольного использования вашим процессом. Ни один другой процесс не сможет открыть этот файл.
Более того, если другой процесс уже открыл этот файл и вы не указываете аргумент File. Share, конструктор File. Stream не сработает. Указать режим совместного доступа к файлу позволяет аргумент File. Share.
Перечисление File. Share None Read Write 0 Другие процессы не будут иметь доступа к файлу; значение по умолчанию. 1 Разрешает другим процессам чтение из файла. 2 Read. Write 3 Разрешает другим процессам запись в файл. Дает другим процессам полный доступ к файлу.
• Обычно, если вы собираетесь только читать файл, другим процессам также разрешается читать его; • иначе говоря, File. Access. Read следует использовать совместно с File. Share. Read. Это правило работает в обе стороны: • если другой процесс открываетфайл с аргументами File. Access. Read и File. Share. Read, ваш процесс не сможет открыть его с другими аргументами.
Свойства и методы File. Stream • После того, как вы открыли файл, создав объект File. Stream, можете обращаться к следующим пяти свойствам, реализованным в классе Stream и переопределенным в'классе File. Stream.
Свойства Stream Тип bool long Свойства Can. Read Can. Write Can. Seek Length Доступ Чтение long Position Чтение/Запись
• Первые два зависят от значения File. Access, указанного при создании объекта File. Stream. • Свойство Can. Seek всегда равно true для открытых файлов. Оно может быть false для других типов потоков (к примеру, сетевых). • Свойства Length и Position применимы только к потокам, в которых возможно позиционирование. Заметьте, что Length и Position — целые числа, имеющие тип long, и теоретически обеспечивают размер файла до 9 терабайт, • Простой способ перемещаться по файлу — применение свойства Position. • Например, если fs — объект типа File. Stream, следующее выражение позволяет перейти на сотый байт в файле:
• fs. Position = 100; • Перейти на конец файла (например, чтобы дописывать данные) можно так: • fs. Position = fs. Length;
Методы File. Stream • int Read. Byte(); • int Read(byte[] aby. Buffer, int i. Buffer. Offset, int i. Count); • void Write. Byte(byte by. Value); • void Write(byte[] aby. Buffer, int i. Buffer. Offset, int i. Count); • long Seek(long i. Offset, Seek. Origin so); • void Set. Length(long i. Size); • void Flush(); • void Close();
• Для чтения одного байта можно применить Read. Byte, для чтения нескольких — Read. Оба метода возвращают значение int, но интерпретируется оно для них поразному. • Read. Byte в случае нормального исполнения возвращает следующий байт из файла, приведенный к типу int без знака. • Read возвращает количество прочитанных в буфер байтов (не более i. Count). • Для файлов Read возвращает значение, равное i. Count, если только i. Count не превышает количества оставшихся в файле байтов. Возвращаемое значение 0 указывает на то, что в файле больше не осталось байтов.
• Второй аргумент методов Read и Write является смещением в буфере, а не в потоке! • Метод Seek похож на функции перемещения по файлу в языке С. Перечисление Seek. Origin определяет точку отсчета для аргумента l. Offset метода Seek: • Begin • Current • End 0 1 2
• Если поток допускает запись и позиционирование, метод Set. Length устанавливает новую длину файла, возможно, обрезая часть содержимого, если новое значение длины файла меньше старого. Метод Flush записывает все данные из буферов в памяти в файл, • Независимо от того, что может произойти или не произойти после сбора мусора для объекта File. Stream, всегда явно вызывайте метод Close для всех открытых вами файлов.
• Если не обращать внимания на обработку исключений, в большинстве случаев вы можете прочесть весь файл в память четырьмя операторами, включая выделение буфера памяти в соответствии с размером файла: • File. Stream fs = new File. Stream("My. File", File. Mode. Open, File. Access. Read, File. Share. Read); • Byte[] aby. Buffer = new Byte[fs. Length]; • fs. Read(aby. Buffer, 0, (int) fs. Length); • fs. Close();
• «В большинстве случаев» , так как в этом коде предполагается, что длина файла меньше, чем 2 Гб. Точнее, это предположение принимается во внимание приведении последнего аргумента метода Read от 64 битного long к 32 -битному int. • Если длина файла более 2 Гб, для его чтения потребуется несколько вызовов Read.
Ввод-вывод двоичных файлов • По определению любой файл, не являющийся текстовым, — двоичный. Ранее рассмотренный класс File. Stream, позволял читать и записывать байты. • Но большинство двоичных файлов состоит из таких данных, типы которых требуют для своего хранения несколько байтов. • Для этой цели можно использовать классы Binary. Writer и Binary. Reader которые определяют методы для чтения и записи многих встроенных типов.
Запись и чтение двоичных данных Чтение и запись этих данных осуществляется с помощью компактного внутреннего двоичного формата, а не в текстовой форме. • • На самом деле классы Binary. Writer и Binary. Reader не записывают данные в файл сами. Они представляют из себя оболочки для некоторого байтового потока. Этот байтовый поток отвечает за чтение и запись последовательностей байт.
• Конструкторы этих классов требуют объект Stream. Если вам нужно использовать с этими классами файл, сперва создайте новый объект типа File. Stream. • Конструктор Binary. Writer • Binary. Writer(Stream stream)
Конструктор для Binary. Reader выглядят точно так же: Конструктор Binary. Reader(Stream stream) Оба класса содержат единственное неизменяемое свойство — Base. Stream, представляющее собой объект Stream, переданный конструктору.
Открытые методы Binary. Writer • void Write(. . . ); • void Write(byte[] aby. Buffer, int i. Buffer. Offset, int i. Bytes. To. Write); • void Write(char[] ach. Buffer, int i. Buffer. Offset, int i. Bytes. To. Write); • long Seek(int i. Offset, Seek. Origin so); • void Flush(); • void Close();
• В качестве параметра для Write может быть использован объект любого базового типа (bool, byte, sbyte, byte[], char[], string, short, ushort, int, uint, long, ulong, float, double или decimal).
Методы Binary. Reader • bool Read. Boolean(); • byte Read. Byte(); • byte[] Read. Bytes(int i. Count); • sbyte Read. SByte(); • char Read. Char(); • char[] Read. Chars(int i. Count); • short Readlnt 16(); • int Readlnt 32(); • long Readlnt 64(); • ushort Read. UInt 16(); • uint Read. UInt 32(); • ulong Read. UInt 64(); • float Read. Single(); • double Read. Double(); • decimal Read. Decimal();
• Также возможно чтение отдельных символов или массивов байтов и символов: Методы Binary. Reader • int Peek. Char(); • int Read(); • void Read(byte[] aby. Buffer, Int IBuffer. Offset, int i. Bytes. To. Read) • void Read(char[] ach. Buffer, int i. Buffer. Offset, int i. Bytes. To. Read); • void Close(); • Методы Peek. Char() и Read() оперируют с символами, а не байтами и предполагают, что кодировка файла — UTF-8, если в конструкторе не была явно указана кодировка. Эти методы возвращают -1, если был достигнут конец файла
Методы класса Binary. Writer §Метод Close закрывает базовый поток. §Метод Flush производит запись буферизованных данных. §Различные перегрузки метода Write позволяют записывать массивы байт и символов а также все примитивные типы в двоичном формате в поток. §Свойство Base. Stream базовому потоку. предоставляет доступ к
Методы класса Binary. Reader §Метод Close закрывает базовый поток. §Метод Read. Bytes считывает последовательность байт из потока. §Метод Read. Chars считывает последовательность символов из потока. §Различные методы Read. X позволяют считывать все примитивные типы в двоичном формате из потока. §Свойство Base. Stream базовому потоку. предоставляет доступ к
Запись двоичных данных static void Main() { Console. Write. Line("***** Запись в файл *****n"); } File. Info f = new File. Info(@"C: Bin. File. dat"); Binary. Writer bw = new Binary. Writer(f. Open. Write()); double a. Double = 20. 09; int an. Int =2009; string a. String ="Привет Мир!"; bw. Write(a. Double); bw. Write(an. Int); bw. Write(a. String); bw. Close();
Чтение двоичных данных static void Main() { Console. Write. Line("***** Чтение из файла *****n"); File. Info f = new File. Info(@"C: Bin. File. dat"); Binary. Reader bw = new Binary. Reader(f. Open. Read()); double a. Double = bw. Read. Double(); int an. Int = bw. Read. Int 32(); string a. String = bw. Read. String(); Console. Write. Line("Из файла считали {0}, {1}, {2} ", a. Double, an. Int, a. String); bw. Close(); }
парадигмы-лек_1-мод_3.ppt