【问题标题】:invalid find handle when iterating directory on Windows在 Windows 上迭代目录时查找句柄无效
【发布时间】:2019-09-16 09:59:03
【问题描述】:

在遍历本地目录(根据错误检查到位)时,我遇到了无效文件错误,但是我无法确定究竟是什么导致了这种情况。有什么明显的原因可能导致这种情况吗?

#define MAX_PATHNAME_LEN 260

int main(int argc, char* argv[])
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    DWORD dwError;
    char DirSpec[MAX_PATHNAME_LEN];

    argv[0] = "\N:\\Joe\\My Documents\\";
    snprintf(DirSpec, "%s\\*", argv[0]);

    // Find the first file in the directory.
    hFind = FindFirstFile(DirSpec, &FindFileData);
    if (hFind == INVALID_HANDLE_VALUE)
    {
        printf("Invalid file handle. Error is %u.\n", GetLastError());
        return (-1);
    }
    else
    {
        printf("First file name is %s.\n", FindFileData.cFileName);  
            // List all the other files in the directory.
            while (FindNextFile(hFind, &FindFileData) != 0)
            {
                printf("Next file name is %s.\n", FindFileData.cFileName); 
            }

        dwError = GetLastError();
        FindClose(hFind);
        if (dwError != ERROR_NO_MORE_FILES)
        {
            printf("FindNextFile error. Error is %u.\n", dwError);
            return (-1);
        }
    }

    return (0);
}

目录是正确的,但在文件夹中扫描似乎不正确。我正在使用 Visual Studio 2019 编写/编译它。

【问题讨论】:

  • argv[1] =... ?你确定 argv 有 2 个元素吗?
  • 您至少有两个问题。 argv[]不属于你修改。它用于传递给main() 的命令行参数。无论如何,您不应该分配给argv[0];它是您自己的可执行文件的完整路径和文件名。 \N: 应该代表什么?这是一个无效的驱动器说明符,因此您的 目录正确 不正确。 (哦,还有第三个问题:MAX_PATHNAME_LEN=200 是错误的。在现代 Windows 版本下,路径名中可以有 200 多个字符。)
  • 除上述之外,snprintf(DirSpec, ... 行在DirSpec 中放置了 4 个连续的反斜杠,所以转义后是 2 个。
  • @WeatherVane,连续的斜线被折叠成一个斜线,除非显然不在路径的开头。
  • @WeatherVane,您说的是在字符串文字中转义反斜杠。我说的是在 Windows 路径规范化中折叠正斜杠和反斜杠。可以在路径中重复斜杠,但开头除外,因为它是 UNC 路径的特殊情况。

标签: c windows file loops


【解决方案1】:

首先,你不需要定义

#define MAX_PATHNAME_LEN 260

Windows 已经定义了

#define MAX_PATH 260

其次,如果您因为是网络共享而添加了N:驱动器,则它需要是\\\\N:\\,这样转义的字符串就是\\N:\

第三,你真的不应该写信给argv[]。 C 标准绝对没有规定它是可写的,并且您无法知道您是否正在注销缓冲区的末尾。改用这个:

char basePath[] = "\\\\N:\\Joe\\My Documents\\";

您对snprintf(DirSpec, "%s\\*", argv[0]); 的调用不包括目标缓冲区的长度,因此它是如何解决的问题。试试

snprintf(DirSpec, MAX_PATH, "%s*", basePath);

请注意,反斜杠已从格式字符串中删除,因为FindFirstFile() 函数的目录内容的通配符是DirPath\*,并且您的基本路径已经以反斜杠结尾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多