Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VC_Lect.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
15 Мб
Скачать
☆

12.4.Поиск файлов и каталогов по заданному пути и маске

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

#include "stdafx.h"

#include "FindFilesVC.h"

#include <io.h>

#include <conio.h>

//опускаем директивы препроцессора

CWinApp theApp;

using namespace std;

/* ProcessMessages() - выполняет обработку сообщений Windows для того,

чтобы приложение смогло обработать нажатие кнопки пользователем

в процессе поиска файлов и каталогов.

Если эту функцию не вызвать, то приложение

не будет реагировать на команды пользователя во время выполнения

«длинного» цикла.

*/

void ProcessMessages()

{ MSG Message;

if(PeekMessage(&Message, NULL, 0,0,PM_REMOVE))

{

TranslateMessage(&Message);

DispatchMessage(&Message);

}

}

/*ShowFiles - поиск файлов, удовлетворяющих маске FileSpec и имеющих

атрибуты FileAttr. Ограничением функции является то, что она

не обрабатывает должным образом символы * и ?, которые могут быть

в маске, и всегда отыскивает файлы с любыми именами.

Вызов функции может иметь такой вид: ShowFiles("C:\\Temp\\*.*", _A_ARCH);

Другие атрибуты файлов, объявленные в io.h:

_A_NORMAL 0x00 Normal file - No read/write restrictions

_A_RDONLY 0x01 Read only file

_A_HIDDEN 0x02 Hidden file

_A_SYSTEM 0x04 System file

_A_SUBDIR 0x10 Subdirectory

_A_ARCH 0x20 Archive file

Атрибуты файлов можно комбинировать с помощью операции |

Обратите внимание, что маска FileSpec, передаваемая функции ShowFiles()

в качестве параметра, должна заканчиваться символами "*.*", так как

это ограничение заложено в коде функции. ОБЯЗАТЕЛЬНО!

*/

void ShowFiles(char * FileSpec, unsigned int FileAttr)

{

const int FNameWidth=40, FSizeWidth=10;

/* FNameWidth и FSizeWidth - максимальное число символов в имени файла

и число цифр в его размере соответственно, которые в данной версии

программы используются только для вывода на монитор

*/

_finddata_t FileInfo;

long hFile;

CString s, NewFileSpec, Mask="*.*";

char Spaces[]=" ";

ProcessMessages(); /* чтобы можно было, например, суметь нажать кнопку.

Вызов функции ProcessMessages() для консольного приложения

в нынешней его реализации необязателен*/

/* _findfirst() - начинаем поиск файлов и каталогов по заданной

в FileSpec маске. Информацию о найденном файле или каталоге получим

в структуре FileInfo

*/

hFile=_findfirst(FileSpec, &FileInfo);

if(hFile == -1L) return; // пустой каталог?

do

{

/* если найден файл с заданным атрибутом, то выводим его.

ctime() преобразует упакованные дату и время создания файла

в формате строки символов

*/

char *DateTime=ctime(&(FileInfo.time_write));

DateTime[strlen(DateTime)-1]=0; /* "затираем" символ перевода строки,

который нам не нужен */

FileInfo.attrib=FileInfo.attrib & 0x00ff; /* Избавляемся от старшего

байта атрибута, который может быть ненулевым в некоторых

случаях, например, у файлов, находящихся на защищенном от записи

диске*/

if(((FileInfo.attrib & FileAttr)==FileAttr) /* если атрибут файла

совпадает с заданным */

&& (FileInfo.name[0]!='.') /* если найденный файл не есть

ссылка на вышестоящий каталог */

&& (!(FileInfo.attrib & _A_SUBDIR))) /* если файл не является

каталогом */

{ // выводим имя файла, дату, время и размер

cout.width(FNameWidth);

s=FileInfo.name;

s.CharToOem(); /* на всякий случай преобразуем имя файла в

кодировку MS DOS */

/* С помощью strncat() добавляем требуемое количество

пробелов в строку s для ее выравнивания при выводе*/

strncat(s.GetBuffer(s.GetLength()+FNameWidth), Spaces,

FNameWidth-s.GetLength()-2);

cout<<LPCTSTR(s)<<' '<<DateTime;

cout.width(FSizeWidth);

cout<<FileInfo.size<<endl;

}

/* если найденный файл - каталог, то выводим его имя и организуем

поиск файлов в нем путем рекурсии */

if((FileInfo.attrib & _A_SUBDIR) &&(FileInfo.name[0]!='.'))

{

/*выводим имя каталога в окно консоли*/

cout.width(FNameWidth);

s=strupr(FileInfo.name); /*strupr() - преобразование букв англ.

алфавита в прописные*/

s.CharToOem();

strncat(s.GetBuffer(s.GetLength()+FNameWidth), Spaces,

FNameWidth-s.GetLength());

cout<<LPCTSTR(s)<<' '<<DateTime<<endl;

/*готовим параметры для рекурсивного вызова ShowFiles.

Суть этой задачи. Если, например, в текущее время

FileSpec=="C:\Windows\*.*" и найден каталог

FileInfo.name=="System", то надо вызвать функцию так:

ShowFiles("C:\Windows\System\*.*", FileAttr);

*/

NewFileSpec=FileSpec; //int Delete( int nIndex, int nCount = 1 )

NewFileSpec.Delete(NewFileSpec.GetLength()-Mask.GetLength(),

Mask.GetLength());

NewFileSpec+=FileInfo.name; NewFileSpec+="\\";

NewFileSpec+=Mask;

ShowFiles(NewFileSpec.GetBuffer(NewFileSpec.GetLength()+1), FileAttr);

}

/*цикл продолжается, пока находится файл (или каталог) и

пользователь не нажал какую-либо клавишу*/

}while(!_findnext( hFile, &FileInfo) && !kbhit());

_findclose( hFile );

}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

int nRetCode = 0;

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

{

cerr << _T("Fatal Error: MFC initialization failed") << endl;

nRetCode = 1;

}

else

{

ShowFiles("d:\\Temp\\*.*", 0);

getch();

}

return nRetCode;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]