曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6719|回复: 0
打印 上一主题 下一主题

[文件与IO] FindFirstFile(),FindNextFile() -- 搜索文件函数|FindClose() -- 关闭搜索句柄

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2011-9-16 17:16:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在一个目录里遍历所有的文件包括子目录时需要搭配 FindFirstFile() 和 FindNextFile() 这两个函数来使用。

FindFirstFile() 的声明如下:
[C++] 纯文本查看 复制代码
HANDLE WINAPI FindFirstFile(
LPCTSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
);

它有两个参数,第 1 个参数是一个目录或路径名,它的名称可以包含通配符 (? *)。如果只是要所搜一个特定文件,那么就不需要通配符。第 2 个参数是 WIN32_FIND_DATA 结构的指针,该结构定义如下:
[C++] 纯文本查看 复制代码
typedef struct _WIN32_FIND_DATA {
  DWORD    dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD    nFileSizeHigh;
  DWORD    nFileSizeLow;
  DWORD    dwReserved0;
  DWORD    dwReserved1;
  TCHAR    cFileName[MAX_PATH];
  TCHAR    cAlternateFileName[14];
} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;

第 1 个成员 dwFileAttributes 是文件的属性值;第 2 到 第 4 个成员是三个文件的时间值(创建时间,最后访问时间和最后写入时间)。nFileSizeHigh 和 nFileSizeLow 它们给出当前文件的长度;cFileName 是文件本身的名字,并不是全路径名。cAlternateFileName 是 DOS 8.3 版本的文件名,这个成员现在几乎不用,只有在需要知道文件在老的 FAT16 文件系统里如何命名时才有用。

在遍历一个目录里的所有文件(也包括子目录)时,还需要用 FindNextFile() 这个函数,它会根据 FindFirstFile() 中给出的查找要求自动去查找下一个文件,并查看是否匹配,如果不匹配则继续查找下一个。如果参数无效或者找不到匹配的文件,那么返回 FALSE 。如果是找不到文件,那么用 GetLastError() 会返回 ERROR_NO_MORE_FILES

在搜索完毕后,需要关闭搜索句柄。注意此时不是用 CloseHandle() ,否则会导致异常发生,而必须使用 BOOL FindClose (HANDLE hFindFile) 函数。

下面程序遍历程序所在目录下所有文件,包括子目录,但不递归检查子目录,只是简单的列出当前目录下所有文件的名字:
[C++] 纯文本查看 复制代码
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{

    WIN32_FIND_DATA findData;
    HANDLE searchHandle;


    searchHandle = FindFirstFile(_T("*"), &findData);
    if (searchHandle == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Error opening Search Handle."));
        exit (EXIT_FAILURE);
    }

    do {
        _tprintf(_T("%s\n"), findData.cFileName);
    } while (FindNextFile (searchHandle, &findData));

    FindClose(searchHandle);

    return 0;
}

运行输出:
C:\>listFile.exe
$Recycle.Bin
.rnd
2011-01-18.log
AMD
ATI
Boot
bootmgr
BOOTSECT.BAK
Config.Msi
dnspod.SDK_log.console.txt
Documents and Settings
Download
Downloads
DriversDownBySODRV
... ...

测试程序2(指定某个目录,非递归查询):
[C++] 纯文本查看 复制代码
#include "stdafx.h"

DWORD TraverDir (LPTSTR szPath)
{
    setlocale(LC_ALL, "chs");

    WIN32_FIND_DATA FindFileData;
    HANDLE hListFile;
    TCHAR szFilePath[MAX_PATH];

    lstrcpy (szFilePath, szPath);

    lstrcat (szFilePath, TEXT("\\*"));

    hListFile = FindFirstFile (szFilePath, &FindFileData);

    if (hListFile == INVALID_HANDLE_VALUE) {
        _tprintf (TEXT("错误:%d"), GetLastError());
        return 1;
    } else {

        do {
            _tprintf (TEXT("%s"), FindFileData.cFileName);    //

            if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) {
                _tprintf (TEXT("\t\t<加密>  "));
            }

            if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
                _tprintf (TEXT("\t\t<隐藏>  "));
            }

            if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                _tprintf (TEXT("\t\t<DIR>"));
            }

            _tprintf (TEXT("\n"));
        } while (FindNextFile(hListFile, &FindFileData));
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "chs");

    if (argc == 2) {
        TraverDir(argv[1]);
    } else {
        TCHAR szCurrentPath[MAX_PATH];
        GetCurrentDirectory(MAX_PATH, szCurrentPath);
        TraverDir(szCurrentPath);
    }

    return 0;
}

运行输出:
D:\WinAPI\TraverseDir\Debug>TraverseDir.exe D:\winapi\TraverseDir
. <DIR>
..<DIR>
Debug <DIR>
ipch<DIR>
TraverseDir <DIR>
TraverseDir.opensdf <隐藏>
TraverseDir.sdf
TraverseDir.sln
TraverseDir.suo <隐藏>
若是不希望显示 . 和 .. 这两个目录,那么可以添加下面代码:
[Plain Text] 纯文本查看 复制代码
 if (lstrcmp(FindFileData.cFileName, TEXT(".")) == 0 || lstrcmp(FindFileData.cFileName, TEXT("..")) == 0) { continue; }

此外还可以根据属性表中的内容添加判断文件的其它属性。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-18 14:54 , Processed in 0.131219 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表