-1

我正在尝试列出文件夹的所有内容(包括子文件夹及其文件),例如 ls -R 与 Linux (我使用的是 Windows 10)

我已经有了这个带有“dirent.h”的基本代码

#include <stdio.h>
#include <dirent.h>

int main()
{
DIR *rep ;
struct dirent *file ;

rep = opendir ("c:\test") ;
if (rep != NULL)
{
while (file = readdir(rep))
printf ("%s\n", file->d_name) ;
(void) closedir (rep) ;
}
return 0;
}

它很好地列出了文件夹的内容,但不浏览子文件夹例如它可以浏览整个硬盘驱动器,如 C:/

我不能使用 d_type 来检测内容是文件还是文件夹,因为对于 windows,结构是:

struct dirent
{
    long        d_ino;      /* Always zero. */
    unsigned short  d_reclen;   /* Always zero. */
    unsigned short  d_namlen;   /* Length of name in d_name. */
    char        d_name[260]; /* [FILENAME_MAX] */ /* File name. */
};

所以我被困在这个问题上,如果有人有想法,甚至是代码


编译器:MinGW32 1.5.0

4

1 回答 1

0

这是 Windows 目录列表的示例。

我使用 Microsoft Visual Studio Community 2019 构建。它作为 Unicode Windows 应用程序工作。也就是说,名称包含非 ASCII 字符的文件和文件夹得到了正确处理。

为此,我使用了 Windows 典型的数据类型和函数:

char    -> WCHAR
strcpy  -> wcscpy
strcat  -> wcscat
strncmp -> wcsncmp
printf  -> wprintf

根据您使用的编译器,您可以使用标准数据类型和函数。字符串常量以 L 为前缀以指定 Unicode 字符串(16 位字符)。

主要功能是ScanDir获取起始目录和文件掩码。调用示例:

ScanDir(L"C:\\Users\\fpiette\\Documents", L"*.jpg");

ScanDir将扫描指定文件夹中的所有文件,然后再次扫描所有目录ScanDir递归调用。对于每个文件,都会显示大小和文件名(当然您可以显示其他属性,例如时间戳和属性)。对于每个目录,都会显示名称。

基本上,迭代目录是使用 Windows FindFirstFileFileNextFile 完成的。

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#include <Windows.h>

BOOL ScanDir(
    WCHAR* srcDir,
    WCHAR* fileMask)
{
    WIN32_FIND_DATA fd;
    HANDLE fh;
    BOOL more;
    WCHAR fromDir[MAX_PATH];
    BOOL found;
    _int64 fileSize;

    wcscpy(fromDir, srcDir);
    wcscat(fromDir, L"\\");
    wcscat(fromDir, fileMask);

    // First step: process files in current dir
    fh = FindFirstFile(fromDir, &fd);
    more = fh != INVALID_HANDLE_VALUE;
    found = FALSE;
    while (more) {
        // Ignore directories in first step
        if (0 == (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
            if (!found) {
                // For the first file found, display the title
                found = TRUE;
                wprintf(L"\nDirectory %s\n\n", srcDir);
            }
            fileSize = ((_int64)fd.nFileSizeHigh << 32) + fd.nFileSizeLow;
            // display file information
            wprintf(L"%12lld %s\n", fileSize, fd.cFileName);
        }
        more = FindNextFile(fh, &fd);
    }
    FindClose(fh);

    // Second step: recursively process subfolders
    wcscpy(fromDir, srcDir);
    wcscat(fromDir, L"\\*.*");
    fh = FindFirstFile(fromDir, &fd);
    more = fh != INVALID_HANDLE_VALUE;
    while (more) {
        // Ignore files in second step
        if (0 != (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
            // We have a directory, process it recursively
            if (wcsncmp(fd.cFileName, L".", 2) &&    // Ignore current directory "."
                wcsncmp(fd.cFileName, L"..", 3)) {   // Ignore parent directory ".."
                wcscpy(fromDir, srcDir);
                wcscat(fromDir, L"\\");
                wcscat(fromDir, fd.cFileName);
                if (!ScanDir(fromDir, fileMask))
                    return 0;
            }
        }
        more = FindNextFile(fh, &fd);
    }
    FindClose(fh);

    return TRUE;
}

int main()
{
    // Change console output to unicode 16 bit (default is OEM)
    _setmode(_fileno(stdout), _O_U16TEXT);
    ScanDir(L"C:\\Users\\fpiette\\Documents", L"*.jpg");
    return 0;
}
于 2021-07-02T07:30:57.090 回答