Searching for a File or Directory

Other versions of this page are also available for the following:

Windows Mobile Not SupportedWindows Embedded CE Supported

8/28/2008

Use the FindFirstFile, the FindNextFile, and the FindClose functions to search for file names or directory names that match a specified pattern. The pattern must be a valid file name and can include the asterisk (*) and question mark (?) wildcards.

To find a single file or a series of files

  1. Call the FindFirstFile function with the file name that is passed in with the lpFileName parameter.

    FindFirstFile returns a handle that you can use in calls to FindNextFile. FindFirstFile also returns the file name, alternate file name, file size, Windows Embedded CE object identifier, attributes, creation time, last access time, and last write time of the file.

  2. If necessary, call FindNextFile with the handle that was returned by FindFirstFile.

    FindNextFile returns the same data as FindFirstFile. You can call FindNextFile multiple times to find instances of the same file.

  3. Modify the file, as necessary.

  4. Destroy the handle that was created by FindFirstFile by using FindClose.

The following code example shows how to copy all .txt files to a new directory, Textro, which contains read-only files. The example also shows how to change all of the files in the new directory to read-only, if necessary. In the example, FindFirstFile and FindNextFile search the root directory for all .txt files. Each .txt file is then copied into Textro. If a file is not read-only, the example calls the SetFileAttributes function to make the copied file read-only. After all of the .txt files are copied, FindClose closes the search handle.

void FindFileExample (void)
{
   WIN32_FIND_DATA FileData; // Data structure describes the file found
   HANDLE hSearch; // Search handle returned by FindFirstFile
   const size_t cchDest = MAX_PATH  // Set the buffer size for the file name
   TCHAR szMsg[cchDest]; // String to store the error message
   TCHAR szNewPath[cchDest]; // Name and path of the file copied
   TCHAR szDirPath[] = TEXT("\\TEXTRO");
   BOOL bFinished = FALSE;
   // Create a new directory.
   if (!CreateDirectory (szDirPath, NULL))
   {
      StringCchPrintf (szMsg, cchDest, TEXT("Unable to create new directory."));
      return;
   }
   // Start searching for .txt files in the root directory.
   hSearch = FindFirstFile (TEXT("\\*.txt"), &FileData);
   if (hSearch == INVALID_HANDLE_VALUE)
   {
      StringCchPrintf (szMsg, cchDest, TEXT("No .TXT files found."));
      return;
   }
   // Copy each .txt file to the new directory and change it to read-only, if it is not already read-only.
   while (!bFinished)
   {
      PathCombine(szNewPath, szDirPath, FileData.cFileName);
      if (NULL != szNewPath && CopyFile (FileData.cFileName, szNewPath, FALSE))
      {
         if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
         {
            SetFileAttributes (szNewPath, FileData.dwFileAttributes | FILE_ATTRIBUTE_READONLY);
         }
      }
      else
      {
         StringCchPrintf (szMsg, cchDest, TEXT("Unable to copy file."));
         // Your error-handling code goes here.
      }
      if (!FindNextFile (hSearch, &FileData))
      {
         bFinished = TRUE;
         if (GetLastError () == ERROR_NO_MORE_FILES)
         {
            StringCchPrintf (szMsg, cchDest, TEXT("Found all of the files."));
         }
         else
         {
            StringCchPrintf (szMsg, cchDest, TEXT("Unable to find next file."));
         }
      }
   }
   // Close the search handle.
   if (!FindClose (hSearch))
   {
      StringCchPrintf (szMsg, cchDest, TEXT("Unable to close search handle."));
   }
}

See Also

Concepts

Obtaining and Setting File Information
File System Operations