/* Подготовка к обходу каталога. */
SetCurrentDirectory(FindData.cFileName);
TraverseDirectory(_T("*"), NumFlags, Flags);
/* Рекурсивный вызов. */
SetCurrentDirectory(_T(".."));
}
} while (FindNextFile(SearchHandle, &FindData));
FindClose (SearchHandle);
}
return TRUE;
}
static BOOL ProcessItem(LPWIN32_FIND_DATA pFileData, DWORD NumFlags, LPBOOL Flags)
/* Выводит список атрибутов файла или каталога. */
{
const TCHAR FileTypeChar[] = {' ', 'd'};
DWORD FType = FileType(pFileData);
BOOL Long = Flags[1];
SYSTEMTIME LastWrite;
if (FType != TYPE_FILE && FType != TYPE_DIR) return FALSE;
_tprintf(_T ("\n"));
if (Long) { /* Указан ли в командной строке параметр "-1"? */
_tprintf(_T("%c"), FileTypeChar[FType – 1]);
_tprintf(_T("%10d"), pFileData->nFileSizeLow);
FileTimeToSystemTime(&(pFileData->ftLastWriteTime), &LastWrite);
_tprintf(_T(" %02d/%02d/%04d %02d:%02d:%02d"), LastWrite.wMonth, LastWrite.wDay, LastWrite.wYear, LastWrite.wHour, LastWrite.wMinute, LastWrite.wSecond);
}
_tprintf(_T(" %s"), pFileData->cFileName);
return TRUE;
}
static DWORD FileType(LPWIN32_FIND_DATA pFileData)
/* Поддерживаемые типы файлов – TYPE_FILE: файл; TYPE_DIR: каталог; TYPE_DOT: каталоги . или .. */
{
BOOL IsDir;
DWORD FType;
FType = TYPE_FILE;
IsDir = (pFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (IsDir) if (lstrcmp(pFileData->cFileName, _T(".")) == 0 || lstrcmp(pFileData->cFileName, _T("..")) == 0) FType = TYPE_DOT;
else FType = TYPE_DIR;
return FType;
}
Пример: установка меток времени файла
Программа 3.3 реализует UNIX-команду touch, предназначенную для изменения кода защиты файлов и обновления меток времени до текущих значений системного времени. В упражнении 3.11 от вас требуется расширить возможности функции touch таким образом, чтобы новые значения меток времени можно было указывать в параметрах командной строки.
Программа 3.3. touch: установка меток даты и времени файла
/* Глава 3. команда touch. */
/* touch [параметры] [файлы] */
#include "EvryThng.h"
int _tmain(int argc, LPTSTR argv[]) {
SYSTEMTIME SysTime;
FILETIME NewFileTime;
LPFILETIME pAccessTime = NULL, pModifyTime = NULL;
HANDLE hFile;
BOOL Flags[MAX_OPTIONS], SetAccessTime, SetModTime, CreateNew;
DWORD CreateFlag;
int i, FileIndex;
FileIndex = Options(argc, argv, _T("amc"), &Flags[0], &Flags[1], &Flags[2], NULL);
SetAccessTime = !Flags[0];
SetModTime = !Flags[1];
CreateNew = !Flags[2];
CreateFlag = CreateNew ? OPEN_ALWAYS : OPEN_EXISTING;
for (i = FileIndex; i < argc; i++) {
hFile = CreateFile(argv[i], GENERIC_READ | GENERIC_WRITE, 0, NULL, CreateFlag, FILE_ATTRIBUTE_NORMAL, NULL);
GetSystemTime(&SysTime);
SystemTimeToFileTime(&SysTime, &NewFileTime);
if (SetAccessTime) pAccessTime = &NewFileTime;
if (SetModTime) pModifyTime = &NewFileTime;
SetFileTime(hFile, NULL, pAccessTime, pModifyTime);
CloseHandle(hFile);
}
return 0;
}
Стратегии обработки файлов
Уже на ранних стадиях любого проекта разработки приложения или подготовки его к переносу на другую платформу приходится принимать решение относительно того, должна ли осуществляться обработка файлов с использованием функций библиотеки С или функций Windows. Характер этого решения не относится к категории "или-или", поскольку при соблюдении определенных мер предосторожности смешанное применение функций возможно даже по отношению к одному и тому же файлу.
Библиотека С обладает рядом явных преимуществ, среди которых можно выделить следующие:
• Полученный программный код легко переносится на другие системы.
• Наличие удобных функций для работы с символами и строками, не имеющих прямых аналогов среди функций Windows, упрощает обработку строк.
• Функции библиотеки С обычно проще в использовании по сравнению с функциями Windows.
• Функции, ориентированные на обработку символьных строк и потоков, легко преобразовать к форме, допускающей указание обобщенных символов при их вызове, хотя преимущества переносимости при этом будут утеряны.
• Как показано в главе 7, функции библиотеки С способны работать и в средах с многопоточной поддержкой.
Тем не менее, использование библиотеки С налагает некоторые ограничения. В пользу этого утверждения можно привести перечисленные ниже соображения:
• Средства библиотеки С не обеспечивают управление каталогами и обход дерева каталогов и в большинстве случаев не позволяют получать или устанавливать атрибутов файлов.
• В функции fseek, входящей в библиотеку С, используются 32-битовые указатели файла, и поэтому, несмотря на возможность последовательного считывания гигантских файлов, установка произвольной позиции в таком файле, как это требуется, например, в программе 3.1, оказывается невозможной.
Читать дальше