Example: Listing File Attributes
It is now time to illustrate the file and directory management functions. Program 1, lsW, shows a limited version of the UNIX ls directory listing command, which is similar to the Windows DIR command. lsW can show file modification times and the file size, although this version gives only the low order of the file size.
The program scans the
directory for files that satisfy the search pattern. For each file
located, the program shows the file name and, if the -l option is specified, the file attributes. This program illustrates many, but not all, Windows directory management functions.
The bulk of Program 1
is concerned with directory traversal. Notice that each directory is
traversed twice—once to process files and again to process
subdirectories—in order to support the -R recursive option.
Program 1, as listed here, will properly carry out a command with a relative pathname such as:
It will not work properly, however, with an absolute pathname such as:
lsW -R C:\Projects\ls\Debug\*.obj
because the program, as listed, depends on setting the directory relative to the current directory. The complete solution (in Examples) analyzes pathnames and will also carry out the second command.
An exercise suggests modifying this program to remove the SetCurrentDirectory calls so as to avoid the risk of program failures leaving you in an unexpected state.
Example: Setting File Times
Program 2 implements the UNIX touch command, which changes file access and modifies times to the current value of the system time.
Program 2. touch: Setting File Times
/* touch [options] files */ #include "Everything.h"
int _tmain(int argc, LPTSTR argv[]) { FILETIME newFileTime; LPFILETIME pAccessTime = NULL, pModifyTime = NULL; HANDLE hFile; BOOL setAccessTime, setModTime, NotCreateNew, maFlag; DWORD createFlag; int i, fileIndex;
fileIndex = Options(argc, argv, _T("amc"), &setAccessTime, &setModTime, &NotCreateNew, NULL);
maFlag = setAccessTime || setModTime; createFlag = NotCreateNew ? OPEN_EXISTING : OPEN_ALWAYS;
for (i = fileIndex; i < argc; i++) { hFile = CreateFile(argv[i], GENERIC_READ | GENERIC_WRITE, 0, NULL, createFlag, FILE_ATTRIBUTE_NORMAL, NULL); /* Get current system time and convert to a file time. Do not change the create time. */ GetSystemTimeAsFileTime(&newFileTime); if (setAccessTime || !maFlag) pAccessTime = &newFileTime; if (setModTime || !maFlag) pModifyTime = &newFileTime; SetFileTime(hFile, NULL, pAccessTime, pModifyTime); CloseHandle(hFile); } return 0; }
|
The program uses GetSystemTimeAsFileTime, which is more convenient than calling GetSystemTime followed by SystemTimeToFileTime. See MSDN for more information, although these functions are straightforward.
Run 2 shows touch operation, changing the time of an existing file and creating a new file.