Скачать презентацию Організація С -системи введення-виведення Лекція 16 1 План Скачать презентацию Організація С -системи введення-виведення Лекція 16 1 План

l17.ppt

  • Количество слайдов: 32

Організація С#-системи введення-виведення Лекція 16 1 Організація С#-системи введення-виведення Лекція 16 1

План Поняття потоку Байтовий потік Символьний потік Двійкові потоки Перенаправлення стандартних потоків 2 План Поняття потоку Байтовий потік Символьний потік Двійкові потоки Перенаправлення стандартних потоків 2

Поняття потоку С#-программи виконують операції введення-виводу за допомогою потоків, які побудовані на ієрархії класів. Поняття потоку С#-программи виконують операції введення-виводу за допомогою потоків, які побудовані на ієрархії класів. Потік (stream) - це абстракція, яка генерує і приймає дані. За допомогою потоку можна читати дані з різних джерел (клавіатура, файл) і записувати в різні джерела (принтер, екран, файл). Не дивлячись на те, що потоки зв'язуються з різними фізичними пристроями, характер поведінки всіх потоків однаковий. Тому класи і методи введеннявиводу можна застосувати до багатьох типів пристроїв. 3

На найнижчому рівні ієрархії потоків введення -виводу знаходяться потоки, що оперують байтами. Це пояснюється На найнижчому рівні ієрархії потоків введення -виводу знаходяться потоки, що оперують байтами. Це пояснюється тим, що багато пристроїв при виконанні операцій введеннявиводу орієнтовано на байти. Проте людина звикла оперувати символами, тому розроблені символьні потоки, які фактично є оболонками, що виконують перетворення байтових потоків в символьні і навпаки. Реалізовані потоки для роботи з int-, double-, short- значеннями, які також представляють оболонку для байтових потоків, але працюють не з самими значеннями, а з їх внутрішнім представленням у вигляді двійкових код. 4

Центральну частину потокової С#-системи займає клас Stream простору імен System. IO Клас Stream представляє Центральну частину потокової С#-системи займає клас Stream простору імен System. IO Клас Stream представляє байтовий потік і є базовим для решти всіх потокових класів. З класу Stream виведені такі байтові класи потоків як: File. Stream - байтовий потік, розроблений для файлового введення-виводу Buffered. Stream - вкладає в оболонку байтовий потік і додає буферизацію, яка у багатьох випадках збільшує продуктивність програми; Memory. Stream - байтовий потік, який використовує пам'ять для зберігання даних 5

Байтовий потік Щоб створити байтовий потік, пов'язаний з файлом, створюється об'єкт класу File. Stream. Байтовий потік Щоб створити байтовий потік, пов'язаний з файлом, створюється об'єкт класу File. Stream. При цьому в класі визначено декілька конструкторів. Найчастіше використовується конструктор, який відкриває потік для читання і/або запису: File. Stream(string filename, File. Mode mode) 6

параметр filename визначає ім'я файлу, з яким буде пов'язаний потік введення-виводу даних; при цьому параметр filename визначає ім'я файлу, з яким буде пов'язаний потік введення-виводу даних; при цьому filename визначає або повний шлях до файлу, або ім'я файлу, який знаходиться в папці bin/debug вашого проекту. параметр mode визначає режим відкриття файлу, який може приймати одне з можливих значень, визначених File. Mode: 7

– File. Mode. Append - призначений для додавання даних в кінець файлу; – File. – File. Mode. Append - призначений для додавання даних в кінець файлу; – File. Mode. Create - для створення нового файлу, (якщо існує файл з таким же ім'ям, то він буде заздалегідь знищений); – File. Mode. Create. New - для створення нового файлу, при цьому файл з таким же ім'ям не має існувати; – File. Mоde. Open - для відкриття існуючого файлу; – File. Mode. Оpen. Or. Create - якщо файл існує, то буде відкритий, інакше буде створений новий – File. Mode. Truncate - відкриває існуючий файл, але усікає його довжину до нуля 8

Якщо файл не відкритий, то генерується одне з виключень: – File. Not. Found. Exception Якщо файл не відкритий, то генерується одне з виключень: – File. Not. Found. Exception - файл неможливо відкрити унаслідок його відсутності, – IOException - файл неможливо відкрити із-за помилки введення-виводу, – Argument. Null. Exception - ім'ям файлу є nullзначення – Argument. Exception – не коректний параметр mode – Security. Exception - користувач не має прав доступу – Directory. Not. Found. Exception - некоректно заданий каталог. 9

Інша версія конструктора дозволяє обмежити доступ тільки зчитуванням або тільки записом: File. Stream(string filename, Інша версія конструктора дозволяє обмежити доступ тільки зчитуванням або тільки записом: File. Stream(string filename, File. Mode mode, File. Access how) де: – параметри filename і mode мають ті ж призначення, – параметр how, визначає спосіб доступу до файлу ( може приймати одне із значень із File. Access): File. Access. Read - тільки читання; File. Access. Write - тільки запис; File. Access. Read. Write - і читання, і запис. 10

Після встановлення зв'язку байтового потоку з фізичним файлом внутрішній покажчик потоку встановлюється на початковий Після встановлення зв'язку байтового потоку з фізичним файлом внутрішній покажчик потоку встановлюється на початковий байт файлу. Для читання чергового байта з потоку, пов'язаного з фізичним файлом, використовується метод Read. Byte(). Після прочитання чергового байта внутрішній покажчик переміщається на наступний байт файлу. Якщо досягнутий кінець файлу, то метод Read. Byte() повертає значення -1. 11

Для побайтового запису даних до потоку використовується метод Write. Byte(). Після закінчення роботи з Для побайтового запису даних до потоку використовується метод Write. Byte(). Після закінчення роботи з файлом його необхідно закрити. Для цього слід викликати метод Close (). При закритті файлу звільняються системні ресурси, раніше виділені для цього файлу, що дає можливість використовувати їх для роботи з іншими файлами. 12

Приклад використання класу File. Stream, для копіювання одного файлу в іншій. Створюєтьсяя текстовий файл Приклад використання класу File. Stream, для копіювання одного файлу в іншій. Створюєтьсяя текстовий файл txt у папці bin/debug поточного проекту і вноситьсяя до нього довільна інформаціяя: Нарешті закінчився цей карантин! Так мені вже набридло! : ) 13

14 14

15 15

Символьний потік Щоб створити символьний потік слід помістити об'єкт класу Stream (наприклад, File. Stream) Символьний потік Щоб створити символьний потік слід помістити об'єкт класу Stream (наприклад, File. Stream) "всередину" об'єкту класу Stream. Writer або об'єкту класу Stream. Reader. В цьому випадку байтовий потік буде автоматично перетворений в символьний. Клас Stream. Writer призначений для організації вихідного символьного потоку. В ньому визначено декілька конструкторів. Один з них записується таким чином: Stream. Writer(Stream stream); – де параметр stream визначає ім'я вже відкритого байтового потоку. 16

Наприклад, створити екземпляр класу Stream. Writer можна таким чином: Stream. Writer file. Out=new Stream. Наприклад, створити екземпляр класу Stream. Writer можна таким чином: Stream. Writer file. Out=new Stream. Writer (new File. Stream("text. txt", File. Mode. Create, File. Access. Write)); Цей конструктор генерує – виключення типу Argument. Exception, якщо потік stream не відкритий для виводу, – і виключення типу Argument. Null. Exception, якщо він (потік) має null-значение. 17

Інший вид конструктора дозволяє відкрити потік відразу через звернення до файлу: Stream. Writer(string name); Інший вид конструктора дозволяє відкрити потік відразу через звернення до файлу: Stream. Writer(string name); – де параметр name визначає ім'я файлу, що відкривається. Наприклад, звернутися до даного конструктора можна таким чином: Stream. Writer file. Out=new Stream. Writer("c: tempt. txt"); 18

І ще один варіант конструктора Stream. Writer: Stream. Writer(string name, bool append. Flag); – І ще один варіант конструктора Stream. Writer: Stream. Writer(string name, bool append. Flag); – де параметр name визначає ім'я файлу, що відкривається; параметр append. Flag може приймати значення true якщо потрібно додавати дані в кінець файлу, або false - якщо файл необхідно перезаписати. Наприклад: Stream. Writer file. Out=new Stream. Writer("t. txt", true); Для запису даних в потік file. Out можна звернутися до методу Write. Line. Це можна зробити таким чином: file. Out. Write. Line("test"); В даному випадку в кінець файлу t. txt буде дописано слово test. 19

Клас Stream. Reader призначений для організації вхідного символьного потоку. Один з його конструкторів виглядає Клас Stream. Reader призначений для організації вхідного символьного потоку. Один з його конструкторів виглядає таким чином: Stream. Reader(Stream stream); – де параметр stream визначає ім'я вже відкритого байтового потоку. – Цей конструктор генерує виключення типу Argument. Exception, якщо потік stream не відкритий для введення. Наприклад, створити екземпляр класу Stream. Writer можна таким чином: Stream. Reader file. In = new Stream. Reader(new File. Stream("text. txt", File. Mode. Open, File. Access. Read)); 20

Як і у випадку з класом Stream. Writer у класу Stream. Reader є і Як і у випадку з класом Stream. Writer у класу Stream. Reader є і інший вид конструктора, який дозволяє відкрити файл безпосередньо: Stream. Reader (string name); – де параметр name визначає ім'я файлу, що відкривається. Звернутися до даного конструктора можна таким чином: Stream. Reader file. In=new Stream. Reader ("c: tempt. txt"); 21

У C# символи реалізуються кодуванням Unicode. Для обробки текстових файлів, що містять російський символи, У C# символи реалізуються кодуванням Unicode. Для обробки текстових файлів, що містять російський символи, створені, наприклад, в Блокноті, рекомендується викликати наступний вид конструктора Stream. Reader: Stream. Reader file. In=new Stream. Reader ("c: tempt. txt", Encoding. Get. Encoding(1251)); – Параметр Encoding. Get. Encoding(1251) визначає перетворення з коду Windows-1251 (одна з модифікацій коду ASCII, що містить російські символи) в Unicode. – Encoding. Get. Encoding(1251) реалізований в просторі імен System. Text. 22

Тепер для читання даних з потоку file. In можна скористатися методом Read. Line. – Тепер для читання даних з потоку file. In можна скористатися методом Read. Line. – При цьому якщо буде досягнутий кінець файлу, то метод Read. Line поверне значення null. приклад, в якому дані з одного файлу копіюються в іншій, але вже з використанням класів Stream. Writer і Stream. Reader. static void Main() { Stream. Reader file. In = new Stream. Reader("text. txt", Encoding. Get. Encoding(1251)); Stream. Writer file. Out=new Stream. Writer("new. Text. txt", false); string line; while ((line=file. In. Read. Line())!=null) //доки потік не порожній { file. Out. Write. Line(line); } file. In. Close(); file. Out. Close(); } 23

Таким чином, даний спосіб копіювання одного файлу в іншій, надає той же результат, що Таким чином, даний спосіб копіювання одного файлу в іншій, надає той же результат, що і при використанні байтових потоків. Проте, його робота буде менш ефективною, оскільки витрачатиметься додатковий час на перетворення байтів в символи. Але символьні потоки маютьсвої переваги. – Наприклад, можна використовувати регулярні вирази для пошуку заданих фрагментів тексту у файлі. static void Main() { Stream. Reader file. In = new Stream. Reader("text. txt"); Stream. Writer file. Out=new Stream. Writer("new. Text. txt", false); string text=file. In. Read. To. End(); Regex r= new Regex(@"[-+]? d+"); Match integer = r. Match(text); while (integer. Success) { file. Out. Write. Line(integer); integer = integer. Next. Match(); } file. In. Close(); file. Out. Close(); } 24

Двійкові потоки Двійкові файли зберігають дані в тому ж вигляді, в якому вони представлені Двійкові потоки Двійкові файли зберігають дані в тому ж вигляді, в якому вони представлені в оперативній пам'яті, тобто у внутрішньому представленні. Двійкові файли не застосовуються для перегляду, вони використовуються тільки для програмної обробки. Вихідний потік Binary. Writer підтримує довільний доступ, тобто є можливість виконувати запис в довільну позицію двійкового файлу. 25

Найбільш важливі методи потоку Binary. Writer: Base. Stream - Визначає базовий потік, з яким Найбільш важливі методи потоку Binary. Writer: Base. Stream - Визначає базовий потік, з яким працює об'єкт Binary. Writer Close - Закриває потік Flush -Очищає буфер Seek –В становлює позицію в поточному потоці Write -Записує значення до поточного потоку 26

Найбільш важливі методи вихідного потоку Binary. Reader: Base. Stream -Визначає базовий потік, з яким Найбільш важливі методи вихідного потоку Binary. Reader: Base. Stream -Визначає базовий потік, з яким працює об'єкт Binary. Reader Close - Закриває потік Peek. Char -Повертає наступний символ потоку без переміщення внутрішнього покажчика в потоці Read - Прочитує черговий потік байтів або символів і зберігає в масиві, передаваному у вхідному параметрі Read. Boolean, Read. Byte, Read. Int 32 тощо Прочитує з потоку дані певного типу 27

Двійковий потік відкривається на основі базового протоку (наприклад, File. Stream), при цьому двійковий потік Двійковий потік відкривається на основі базового протоку (наприклад, File. Stream), при цьому двійковий потік перетворюватиме байтовий потік в значення int-, double-, short тощо Приклад формування двійкового файлу: static void Main() { //відкриваємо двійковий потік Binary. Writer f. Out=new Binary. Writer(new File. Stream("t. dat", File. Mode. Create)); //записуємо дані в двійковий потік for (int i=0; i<=100; i+=2) { f. Out. Write(i); } f. Out. Close(); //закриваємо двійковий потік } 28

Двійковий файл є видимим програмним шляхом, наприклад таким чином: static void Main() { File. Двійковий файл є видимим програмним шляхом, наприклад таким чином: static void Main() { File. Stream f=new File. Stream("t. dat", File. Mode. Open); Binary. Reader f. In=new Binary. Reader(f); long n=f. Length/4; //определяем кількість чисел в двійковому потоці int а; for (int i=0; i

Двійкові файли є файлами з довільним доступом Нумерація елементів в двійковому файлі ведеться з Двійкові файли є файлами з довільним доступом Нумерація елементів в двійковому файлі ведеться з нуля. Довільний доступ забезпечує метод Seek(long new. Pos, Seek. Origin pos) – де параметр new. Pos визначає нову позицію внутрішнього покажчика файлу в байтах щодо вихідної позиції покажчика, яка визначається параметром pos. – У свою чергу параметр pos має бути заданий одним із значень Seek. Origin: – Seek. Origin. Begin - Пошук від початку файлу – Seek. Origin. Current -Пошук від поточної позиції покажчика – Seek. Origin. End - Пошук від кінця файлу 30

Перенаправлення стандартних потоків Трьома стандартними потоками, доступ до яких здійснюється через властивості Console. Out, Перенаправлення стандартних потоків Трьома стандартними потоками, доступ до яких здійснюється через властивості Console. Out, Console. In і Console. Error, можуть користуватися всі програми, що працюють в просторі імен System. Властивість Console. Out відноситься до стандартного вихідного потоку. За замовчуванням це консоль. – Наприклад, при виклику методу Console. Write. Line() інформація автоматично передається в потік Console. Out. Властивість Console. In відноситься до стандартного вхідного потоку, джерелом якого за замовчуванням є клавіатура. – Наприклад, при введенні даних з клавіатури інформація автоматично передається потоку Console. In, до якого можна звернутися за допомогою методу Console. Read. Line(). 31

Властивість Console. Error відноситься до помилок в стандартному потоці, джерелом якого також за умовчанням Властивість Console. Error відноситься до помилок в стандартному потоці, джерелом якого також за умовчанням є консоль. Проте ці потоки можуть бути перенаправлені на будь-який сумісний пристрій введеннявиводу, наприклад, на роботу з фізичними файлами. Перенаправити стандартний потік можна за допомогою методів Set. In(), Set. Out() і Set. Error(), які є членами класу Console: – – – static void Setln(Text. Reader input) static void Set. Out(Text. Writer output) static void Set. Error(Text. Writer output) 32