
25 Робота з каталогами (теками) у Windows.pptx
- Количество слайдов: 21
Робота з каталогами (теками) у Windows Лекція Підготував Шахрайчук М. І. 08. 02. 2018 1
Для створення каталога використовується функція Create. Directory(), яка має наступний прототип: BOOL Create. Directory( LPCTSTR lp. Path. Name, // ім'я каталога LPSECUTITY_ATTRIBUTES Ip. Securuty. Attributes); У разі успішного завершення функція повертає ненульове значення, інакше - FALSE. У параметрі lp. Path. Name задається покажчик на символьний рядок, який містить ім’я створюваного каталога, а параметр Ip. Securuty. Attributes задає атрибути безпеки цього каталога. У лістингу 25. 1 приведена програма, яка створює каталог. 08. 02. 2018 2
// Лістинг 25. 1. Приклад створення каталога #include "stdafx. h" int main() { wchar_t lpsz. File. Name[] = L"C: \Users\Shogun\Documents\demo_dir\"; } // створюємо каталог if (!Create. Directory(lpsz. File. Name, NULL)) { std: : cerr << "Create directory failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } std: : cout << "The directory is created. " << std: : endl; std: : cin. get(); return 0; 08. 02. 2018 3
Після створення теки можна отримати її дескриптор, використавши для цього Create. File() зі встановленим прапорцем FILE_FLAG_BACKUP_SEMANTICS. Створити підкаталог можна використавши функцію Create. Directory. Ex(), яка дозволяє успадковувати атрибути іншого каталога, так званого шаблонного каталога. Як такий, може бути батьківський каталог, в якому створюється поточний каталог. Create. Directory. Ex() має наступний прототип: BOOL Create. Directory. Ex( LPCTSTR lp. Template. Directory, // ім'я шаблонного каталога LPCTSTR lp. New. Directory, // ім'я нового каталога LPSECUTITY_ATTRIBUTES Ip. Securuty. Attributes); // атрибути захисту 08. 02. 2018 4
Наприклад, програма з лістингу 25. 2 створює підкаталог в каталозі створеному програмою з лістингу 25. 1. // Лістинг 25. 2. Приклад створення підкаталога #include "stdafx. h" int main() { wchar_t lpsz. Directory. Name[]=L"C: \Users\Shogun\Documents\demo_dir"; wchar_t lpsz. Sub. Directory. Name[]=L"C: \Users\Shogun\Documents\demo_dir\demo_subdir"; // створюємо підкаталог { } if (!Create. Directory. Ex(lpsz. Directory. Name, lpsz. Sub. Directory. Name, NULL)) std: : cerr << "Create directory failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } std: : cout << "The subdirectory is created. " << std: : endl; std: : cin. get(); return 0; 08. 02. 2018 5
08. 02. 2018 6
Для пошуку файлів у каталозі, використовуються функції Find. First. File() і Find. Next. File(). Причому Find. First. File() знаходить перший файл, ім’я якого задовольняє зразку пошуку, а Find. Next. File() знаходить наступні такі файли. У шаблонах імен файлів для пошуку можуть використовуватися символи-замісники ? і *. Символ ? заміщає один невідомий символ в імені файла, а символ * - будь-яку послідовність символів. Функція Find. First. File(), має наступний прототип: HANDLE Find. First. File( LPCTSTR lp. File. Name, // зразок імені для пошуку LPWIN 32_FIND_DATA lp. Find. File. Data); // адреса даних про файл У разі успішного завершення Find. First. File() повертає дескриптор для пошуку файлів, який використовується надалі Find. Next. File(), інакше - INVALID_HANDLE_VALUE. У параметрі lp. File. Name встановлюється покажчик на символьний рядок із зразком імені файла для пошуку. 08. 02. 2018 7
lp. Find. File. Data вказує на структуру WIN 32_FIND_DATA, в яку функція запише відомості про знайдений файл. Ця структура має наступний формат: typedef struct _WIN 32_FIND_DATA { DWORD dw. File. Attributes; // атрибути файла FILETIME ft. Creation. Time; // час створення файла FILETIME ft. Last. Access. Time; // час останнього доступу до файла FILETIME ft. Last. Write. Time; // час останнього запису у файл DWORD n. File. Size. High; // старша частина розміру файла DWORD n. File. Size. Low; // молодша частина розміру файла DWORD dw. Reserved 0; // тег для перетворення файла DWORD dw. Reserved 1; // не використовується CHAR c. File. Name[MAX_PATH]; // довге ім'я файла CHAR c. Alternate. File. Name[14]; // коротке ім'я файла } WIN 32_FIND_DATA, *PWIN 32_FIND_DATA, *LPWIN 32_FIND_DATA; 08. 02. 2018 8
У разі успішного завершення функція Find. Next. File() записує в цю структуру дані про перший знайдений файл. Відзначимо, що в полі dw. File. Attributes структури WIN 32_FIND_DATA можуть бути встановлені наступні прапорці: q q q q q FILE_ATTRIBUTE_ARCHIVE - архівний файл; FILE_ATTRIBUTE_COMPRESSED - стиснутий файл; FILE_ATTRIBUTE_DIRECTORY - каталог; FILE_ATTRIBUTE_ENCRYPTED - зашифрований файл; FILE_ATTRIBUTE_HIDDEN - прихований файл; FILE_ATTRIBUTE_NORMAL - нормальний файл; FILE_ATTRIBUTE_OFFLINE - файл у зовнішній пам'яті; FILE_ATTRIBUTE_READONLY - файл призначений тільки для читання; FILE_ATTRIBUTE_REPARSE_POINT - файл містить точку перетворення; q FILE_ATTRIBUTE_SPARSE_FILE - розріджений файл; q FILE_ATTRIBUTE_SYSTEM - системний файл; q FILE_ATTRIBUTE_TEMPORARY - тимчасовий файл. 08. 02. 2018 9
Тепер розглянемо функцію Find. Next. File(), яка призначена для знаходження в каталозі наступних файлів після першого знайденого файла. Порядок перерахування файлів залежить від файлової системи. У файловій системі FAT файли перераховуються в порядку їх створення, а у файлових системах NTFS і CDFS - перераховуються в алфавітному порядку. Ця функція має наступний прототип: BOOL Find. Next. File( HANDLE h. Find. File, // дескриптор для пошуку файлів LPWIN 32_FIND_DATA lp. Find. File. Data); // адреса даних про файл У разі успішного завершення функція Find. Next. File() повертає ненульове значення, інакше - FALSE. У параметрі h. Find. File повинен бути встановлений дескриптор для пошуку файлів, який був отриманий викликом функції Find. First. File(). 08. 02. 2018 10
lp. Find. File. Data повинен містити адресу структури типу WIN 32_FIND_DATA, в яку Find. Next. File() при успішному завершенні помістить інформацію про наступний знайдений файл. Відзначимо, що як Find. First. File(), так і Find. Next. File() повертають в структурі типу WIN 32_FIND_DATA інформацію як про файли, так і про підкаталоги. У лістингу 25. 3 приведена програма яка виводить на консоль інформацію про всі файли і підкаталоги заданого каталога. Як видно з результатів, в цей список входять поточний і батьківський каталоги. Завершивши пошук файлів треба викликати функцію Find. Close(), яка закриває дескриптор пошуку файлів і має наступний прототип: BOOL Find. Close( HANDLE h. Find. File); // дескриптор пошуку файла При успішному завершенні ця функція повертає ненульове значення, інакше - FALSE. 08. 02. 2018 11
// Лістинг 25. 3. Приклад пошуку файлів у каталозі #include "stdafx. h" int main() { HANDLE h. Find. File; wchar_t lpsz. Directory. Name[]=L"C: \Users\Shogun\Documents\demo_dir\*"; WIN 32_FIND_DATA fd; // знаходимо перший файл h. Find. File = Find. First. File(lpsz. Directory. Name, &fd); if (h. Find. File == INVALID_HANDLE_VALUE) { std: : cerr << "Find first file failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } // виводимо на консоль ім'я першого файла std: : cout << "The first file name: " << fd. c. File. Name << std: : endl; 08. 02. 2018 12
// знаходимо наступний файл і виводимо на консоль його ім'я while (Find. Next. File(h. Find. File, &fd)) std: : cout << "The next file name: " << fd. c. File. Name << std: : endl; // закриваємо дескриптор пошуку Find. Close(h. Find. File); std: : cin. get(); return 0; } Для більш просунутого пошуку файлів може використовуватися функція Find. First. File. Ex(), яка дозволяє враховувати при пошуку файла не тільки його ім’я, але також і його атрибути. Відзначимо, що ця функція підтримується тільки в ОС Windows NT/2000/XP. 08. 02. 2018 13
Для видалення порожнього каталога призначена функція Remove. Directory(), яка має наступний прототип: BOOL Remove. Directory( LPCTSTR lp. Path. Name ); // ім’я каталога Єдиний параметр цієї функції повинен вказувати на символьний рядок, який містить ім’я каталога, що видаляється. При успішному завершенні функція Remove. Directory() повертає ненульове значення, інакше - FALSE. У лістингу 25. 4 приведена програма, в якій використовується функція Remove. Directory() для видалення каталога. Ще раз відзначимо, що для успішного видалення каталог повинен бути порожній. 08. 02. 2018 14
// Лістинг 25. 4. Приклад видалення порожнього каталога #include "stdafx. h" int main() { wchar_t lpsz. Directory. Name[] = L"C: \Users\Shogun\Documents\demo_dir"; // видаляємо каталог if (!Remove. Directory(lpsz. Directory. Name)) { std: : cerr << "Remove directory failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } std: : cout << "The directory is removed. " << std: : endl; std: : cin. get(); return 0; } 08. 02. 2018 15
На практиці каталог рідко буває порожнім, тому перш ніж видалити сам каталог, потрібно видалити всі підкаталоги, які знаходяться в ньому, і файли. Опишемо, як видаляти з каталога файли. Цей же підхід використовується і для видалення файлів з підкаталогів. У лістингу 25. 5 приведена програма, яка видаляє з каталога файли, а потім видаляє сам каталог. // Лістинг 25. 5. Приклад видалення каталога з файлами #include "stdafx. h" int main() { HANDLE h. Find. File; wchar_t lpsz. First. File. Name[] = L"C: \Users\Shogun\Documents\demo_dir\*"; wchar_t lpsz. Directory. File. Name[]=L"C: \Users\Shogun\Documents\demo_dir\%s"; wchar_t lpsz. Directory. Name[] = L"C: \Users\Shogun\Documents\demo_dir"; 08. 02. 2018 16
WIN 32_FIND_DATA fd; wchar_t sz. Full. File. Name[MAX_PATH]; // знаходимо перший файл h. Find. File = Find. First. File(lpsz. First. File. Name, &fd); if (h. Find. File == INVALID_HANDLE_VALUE) { std: : cerr << "Find first file failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } // виводимо на консоль ім'я першого файла std: : cout << "The first file name: " << fd. c. File. Name << std: : endl; // видаляємо із каталога файли while (Find. Next. File(h. Find. File, &fd)) { // якщо це не підкаталог, то видаляємо його if (!(fd. dw. File. Attributes & FILE_ATTRIBUTE_DIRECTORY)) { // формуємо ім'я файла 08. 02. 2018 17
swprintf(sz. Full. File. Name, lpsz. Directory. File. Name, fd. c. File. Name); // видаляємо файл if (!Delete. File(sz. Full. File. Name)) { std: : cerr << "Delete file failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } else std: : cout << "The next file: " << fd. c. File. Name << " is deleted. " << std: : endl; } else std: : cout << "The next directory: « << fd. c. File. Name << " is not deleted. " << std: : endl; } 08. 02. 2018 18
// закриваємо дескриптор пошуку if (!Find. Close(h. Find. File)) { std: : cout << "Find close failed. " << std: : endl; return 0; } // видаляємо каталог if (!Remove. Directory(lpsz. Directory. Name)) { std: : cerr << "Remove directory failed. " << std: : endl << "The last error code: " << Get. Last. Error() << std: : endl; } std: : cout << "Press any key to finish. "; std: : cin. get(); return 0; } std: : cout << "The directory is removed. " << std: : endl; // закриваємо дескриптор пошуку Find. Close(h. Find. File); std: : cin. get(); return 0; 08. 02. 2018 19
08. 02. 2018 20
Так само як і файли, каталоги можна переміщати за допомогою функції Move. File(). У цьому випадку на виконання функції Move. File() накладається одне обмеження, яке полягає в тому, що можна переміщати тільки каталоги, які знаходяться на одному диску. Нагадаємо, що функція Move. File() має наступний прототип: BOOL Move. File( LPCTSTR Ip. Existing. File. Name, // ім'я існуючого файла LPCTSTR lp. New. File. Name); // м'я ового і н файла При успішному завершенні функція повертає ненульове значення, інакше - FALSE. При переміщенні каталогів параметри Ip. Existing. File. Name і lp. New. File. Name повинні 08. 02. 2018 21 вказувати на рядки, які містять імена переміщуваного і 21
25 Робота з каталогами (теками) у Windows.pptx