|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Уведення-виведення
У колишніх
версіях Visual Basic використовувалися різні засоби обробки даних, причому
вибір визначався типом джерела даних. Наприклад, обробка даних, прочитаних
з файлу на диску, принципово відрізнялася від обробки даних, завантажених
з Інтернету. Ці часи залишилися у минулому. Одній з цілей, поставлених при
проектуванні .NET Framework, було забезпечення уніфікованого механізму обробки
даних, не залежного від джерела. Центральне місце
в цьому механізмі займає поняття потоку (stream). Термін «потік» в
даному випадку походить від виразу «потік байтів». Власне, всі
дані, з якими працює комп'ютер, — числа, текст і графіка — зводяться до
звичайної послідовності байтів. Таким чином, підхід, вибраний проектувальниками .NET
Framework, виглядає цілком логічно — вони розробили абстрактний клас, що
виконує узагальнені операції з даними. Наявність абстрактного класу спрощує
програмування введення-виводу в VB .NET і виявляє схожість між різнорідними
операціями. Коротше кажучи, абстрактний клас Stream, помічений ключовим словом
Mustlnherit, є ідеальною базою для побудови об'єктно-орієнтованої
ієрархії введення-виводу. При роботі
з потоками даних, що поступають з клавіатури, з пам'яті, з файлу
або мережевого з'єднання, програмісти .NET використовують класи, адаптовані
для конкретних джерел. Але перш, ніж розглядати ці типи потоків,
необхідно познайомитися з тим, як організовано локальне зберігання даних
користувачем. З цієї причини ми починаємо цей розділ з опису операцій з файлами і
каталогами, а потім розглянемо існуючі різновиди потоків .NET, зокрема файлові, мережеві
і об'єктні потоки, що дозволяють зберігати об'єкти на диску, і інші
джерела даних. Розділ завершується
прикладом використання нових серверних засобів RAD (Rapid Application Development)
для написання простого монітора файлової системи. Програма стежить за змінами
в каталогах (такими, як створення і видалення файлів) і обробляє різні
події, що ініціюються залежно від типу змін. У попередніх версіях
VB написання подібних програм було сильно утруднене тим, що програмістові
доводилося використовувати Windows API вельми нетривіальним чином. І хоча в
цій книзі ми не зможемо скільки-небудь повно описати Rad-іногоументарій VB .NET,
ми сподіваємося, що це підстебне вашу цікавість і змусить докладніше вивчити
цей надзвичайно корисний аспект VB .NET.
У VB .NET
існують два класи для роботи з каталогами і два класи для роботи з файлами.
Звернення до функціональних можливостей класів Directory і File відбувається
за допомогою загальних методів. Оскільки методи класів Di rectory і Fi1е є
загальними, вони можуть викликатися і без попереднього створення екземпляра
оператором New. Звичайно, це підвищує їх ефективність при разових зверненнях
до конкретного файлу або каталога. Проте при багатократному зверненні до файлу або каталога
ці методи стають менш ефективними. Класи Di rectorylnfo і Filelnfo містять
звичайні методи, тому звернення до їх членів відбувається через конкретні екземпляри. Інша відмінність між
цими парами полягає в тому, що класи Directory і File є похідними безпосередньо
від Object, а класи Directory-info і Fileinfo оголошені похідними від
абстрактного (Mustlnherit) класу Filesysteminfo, що містить універсальні
методи ніби Lastaccesstime і Fullname. Та все
ж найпринциповіша відмінність полягає в іншому. Класи Directorylnfo і Filelnfo
набагато краще підходять для рекурсивного використання результатів, як було
показано в прикладі, приведеному в розділі 4. Річ у тому, що члени класів Directory
і File зазвичай повертають рядки з описом каталогів або файлів, тоді як
члени класів Di rectorylnfo і Filelnfo зазвичай повертають екземпляри своїх класів.
Як було показано в розділі 4, ця особливість спрощує написання рекурсивних
програм. Оскільки існування даних,
до яких ви звертаєтеся, не гарантоване, звернення до файлів
або каталогів часто полягають в блоки Try-catch. Втім, на ці класи розповсюджується
одне з основних правил при роботі з виключеннями: не використовуйте виключення
там, де можна обмежитися простою перевіркою. Наприклад, в звичайних
умовах немає чого перехоплювати виключення Di rectorynotfoundexcepti on
— простіше заздалегідь викликати метод Exists і переконатися в тому, що каталог існує.
Нижче перераховані основні виключення, що зустрічаються при операціях
з файлами і каталогами. Ієрархію очолює базовий клас Ioexception: Ioexception >Directorynotfoundexception >
Endofstreamexception >Fileloadexception >Filenotfoundexception
Перш ніж розглядати
операції з каталогами і файлами, слід познайомитися з класом Path.
Цей клас містить декілька загальних методів, призначених для обробки уточнених
імен файлів [ Цікава подробиця: у описі цього класу, приведенням
в документації VB .NET, згадуються деякі аспекти кросс-платформенних операцій.
Зокрема, згадується про відмінності між символом «/» і роздільником
каталогів «\», використовуваним в системах сімейства UNIX (у
тому числі і в системі BSD, для якої Microsoft анонсувала підтримку CLR). ].
Мережеві імена файлів влаштовані дещо складніше за локальні імена, тому
методи класу Path приносять безперечну користь (до речі кажучи, аналіз
навіть локальних імен — заняття на любителя). Основні члени класу Path перераховані
в таблиці. 9.1. Таблиця
9.1.
Найважливіші члени класу Path
Більшість
методів класу Directory ідентифікують каталоги за допомогою повертаних рядків.
Оскільки всі члени класу оголошені загальними, при зверненні до них не обов'язково
указувати конкретний екземпляр. Приклад: System.IO.Directory.GetCurrentDirectory() Ця команда
повертає рядок з описом поточного каталога. Метод Getdirectories(pathstring)
повертає масив рядків з описом підкаталогів каталога, заданого параметром
pathstring. Опис інтерпретується або як шлях, заданий щодо каталога
поточного застосування, або як шлях в схемі UNC (Universal Naming Convention).
Наступна програма виводить ім'я поточного каталога і імена всіх його підкаталогів. Imports System.IO
Module Modulel Sub Main() Dim curdir.nextDir
As String Try curdir =Directory.GetCurrentDirectory
() Console.WriteLine(curdir) For Each nextdir
In Directory.GetDirectories(curdir) Console.WriteLine(nextdir)
Next Catch
ioe As Ioexception Console.WriteLine("eeeks
-i/o problems!" & ioe.message) Catch e
As Exception Consol e. Write(e.stacktrace)
Finally Console.ReadLine() End Try End Sub End
Module Якщо ваші потреби не обмежуються простим виведенням імен каталогів, краще скористатися класом Directoryinfo. Докладніший опис цього класу приводиться нижче. Окрім передачі
рядка з описом каталога методу Getdirectories можна передати шаблон з метасимволами,
використовуваними в DOS [ «?» позначає один символ, а «*»
— декілька символів. ]. Найважливіші методи класу Di rectory перераховані в
таблиці. 9.2. У всіх випадках параметри передаються за значенням (з ключовим словом
Byval). Таблиця
9.2.
Найважливіші методи класу Directory
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||