使用Win32 API 查找文件

最新修改的代码,见http://www.cnblogs.com/farewell-farewell/p/7197644.html

头文件:#include <windows.h>

//FindFirstFile() 获得指定目录的第一个文件
HANDLE FindFirstFile( LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData );

/*
lpFileName 是搜索目录的名称,注意: \ 需要用转义字符表达。(”E:\\Folder\\“)
lpFindFileData 指向一个用于保存文件信息的结构体。
返回值 调用成功返回HANDLE类型,可用来做为FindNextFile或 FindClose参数;
调用失败 返回为INVALID_HANDLE_VALUE(即-1) ,可调用GetLastError来获取错误信息。
*/
//FindNextFile()判断当前目录下是否有下一个目录或文件
bool FindNextFile(HANDLE hFindFile,  LPWIN32_FIND_DATA lpFindFileData );

/*
HANDLE hFindFile 搜索的文件句柄 函数执行的时候搜索的是此句柄的下一文件
LPWIN32_FIND_DATA lpFindFileData 指向一个用于保存文件信息的结构体

返回值  非零表示成功,零表示失败。如不再有与指定条件相符的文件,会将GetLastError设置成ERROR_NO_MORE_FILES

*/

PS: lpFindFileData用于获取文件信息。通常,最初的两次搜索得到的文件名为:"." 、"..",分别代表当前目录和上级目录。遍历文件时要注意这两个目录。

 

上述函数的属性解析:

1. HANDLE(句柄)

是Windows操作系统中的一个概念。在Windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为它们分配内存,并返回标示这些资源的标示号,即句柄。句柄指的是一个核心对象在某一个进程中的唯一索引,而不是指针。由于地址空间的限制,句柄所标识的内容对进程是不可见的,只能由操作系统通过进程句柄列表来进行维护。句柄列表:每个进程都要创建一个句柄列表,这些句柄指向各种系统资源,比如信号量,线程和文件等,进程中的所有线程都可以访问这些资源。

无效的返回值为: INVALID_HANDLE_VALUE

PS:HANDLE是一个通用句柄表示,HWND是一个专用表示窗口的句柄。

2.LPCTSTR

用来表示字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。

LPCTSTR表示一个指向const对象的指针。

3.LPWIN32_FIND_DATA

WIN32_FIND_DATA的指针。LP表示long pointer的意思。

long pointer的含义(摘):

Some processors have two types of pointers, a near pointer and a far pointer. 
The near pointer is narrower (thus has a limited range) than a far pointer. A far pointer may also be a long pointer.

Some processors offer relative addressing for things nearby. 
A long pointer may indicate that the item is not close by and relative addressing cannot be used.

In any case, long pointers are a platform specific issue and may not be portable to other OSes or platforms.

以下为WIN32_FIND_DATA结构体:

typedef struct _WIN32_FIND_DATA

{

   DWORD dwFileAttributes;                // 文件属性 
   FILETIME ftCreationTime;               // 文件创建时间 
   FILETIME ftLastAccessTime;             // 文件最后一次访问时间 
   FILETIME ftLastWriteTime;              // 文件最后一次修改时间 
   DWORD nFileSizeHigh;                   // 文件长度高 32 位 
   DWORD nFileSizeLow;                    // 文件长度低 32 位 
   DWORD dwReserved0;                     // 系统保留 
   DWORD dwReserved1;                     // 系统保留 
   TCHAR cFileName[ MAX_PATH ];           // 长文件名 
   TCHAR cAlternateFileName[ 14 ];        // 文件的可选名

  } WIN32_FIND_DATA;

 

程序示例:

读取三个文件夹下的文件

#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdlib.h>
#include <windows.h>

using namespace std;


string getstring(const int n)
{
    stringstream str;
    str << n;
    return str.str();
}
wchar_t* CharToWchar(const char* c)
{
    wchar_t *m_wchar;
    int len = MultiByteToWideChar(CP_ACP, 0, c, strlen(c), NULL, 0);
    m_wchar = new wchar_t[len + 1];
    //映射一个字符串到一个宽字符(unicode)的字符串
    MultiByteToWideChar(CP_ACP, 0, c, strlen(c), m_wchar, len);
    m_wchar[len] = '\0';
    return m_wchar;
}
char* WcharToChar(const wchar_t* wp)
{
    char *m_char;
    //映射一个unicode字符串到一个多字节字符串
    int len = WideCharToMultiByte(CP_ACP, 0, wp, wcslen(wp), NULL, 0, NULL, NULL);
    m_char = new char[len + 1];
    WideCharToMultiByte(CP_ACP, 0, wp, wcslen(wp), m_char, len, NULL, NULL);
    m_char[len] = '\0';
    //printf("my char %s\n", m_char);
    return m_char;
}

wchar_t* StringToWchar(const string& s)
{
    const char* p = s.c_str();
    return CharToWchar(p);
}

int main()
{
    string  Name, Path;

    for (int i = 0; i < 3; i++){

        int j = 0;
        Path = getstring(i + 1) + "/" + "*.*";

        HANDLE hFile;
        LPCTSTR lp = StringToWchar(Path);
        WIN32_FIND_DATA pNextInfo;
        hFile = FindFirstFile(lp, &pNextInfo);
        if (hFile == INVALID_HANDLE_VALUE){
            cout << "failed" << endl;
            exit(-1);//搜索失败
        }
        cout << "folder name:" << i + 1 << endl;

        do{
            //必须加这句,不然会加载.和..的文件而加载不了图片,
            if (pNextInfo.cFileName[0] == '.')continue;

            cout << "file name" << WcharToChar(pNextInfo.cFileName) << endl;
            j++;
        } while (FindNextFile(hFile, &pNextInfo));


        system("pause");
        return 0;
}
WideCharToMultiByte与MultiByteToWideChar函数
int WideCharToMultiByte(
UINT CodePage,                  //指定执行转换的代码页
DWORD dwFlags,                  //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
LPCWSTR lpWideCharStr,          //指定要转换为宽字节字符串的缓冲区
int cchWideChar,                //指定由参数lpWideCharStr指向的缓冲区的字符个数
LPSTR lpMultiByteStr,           //指向接收被转换字符串的缓冲区
int cchMultiByte,               //指定由参数lpMultiByteStr指向的缓冲区最大值
LPCSTR lpDefaultChar,           //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
LPBOOL pfUsedDefaultChar        //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
);

/*
CodePage:指定执行转换的代码页,这个参数可以为系统已安装或有效的任何代码页所给定的值。你也可以指定其为下面的任意一值:
CP_ACP:ANSI代码页;CP_MACCP:Macintosh代码页;CP_OEMCP:OEM代码页;
CP_SYMBOL:符号代码页(42);CP_THREAD_ACP:当前线程ANSI代码页;
CP_UTF7:使用UTF-7转换;CP_UTF8:使用UTF-8转换。
*/
int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, 
                                     int cchMultiByte, LPWSTR lpWideCharStr, int cchWideChar);

 

wchar_t是Unicode字符的数据类型

 typedef unsigned short wchar_t;

另外,在头文件中有这样的定义:

typedef wchar_t WCHAR;

所以WCHAR实际就是wchar_t

 
posted @ 2016-11-04 17:39  Not-Bad  阅读(3140)  评论(0编辑  收藏  举报