【获取指定目录下的所有文件名】

1. Linux环境下

1.1 相关函数介绍

在Linux环境下,<dirent.h>是一个应用程序接口,主要用于文件系统的目录读取操作,提供了几个目录数据读取函数。

Linux下通过调用opendir、readdir和closedir三个函数来遍历文件夹得到所有文件名信息。三个函数的声明分别如下:

/* Open a directory stream on NAME.
   Return a DIR stream on the directory, or NULL if it could not be opened.

   This function is a possible cancellation point and therefore not
   marked with __THROW.  */
extern DIR *opendir (const char *__name) __nonnull ((1));

/* Read a directory entry from DIRP.  Return a pointer to a `struct
   dirent' describing the entry, or NULL for EOF or error.  The
   storage returned may be overwritten by a later readdir call on the
   same DIR stream.

   If the Large File Support API is selected we have to use the
   appropriate interface.

   This function is a possible cancellation point and therefore not
   marked with __THROW.  */

extern struct dirent *readdir (DIR *__dirp) __nonnull ((1));

/* Close the directory stream DIRP.
   Return 0 if successful, -1 if not.

   This function is a possible cancellation point and therefore not
   marked with __THROW.  */
extern int closedir (DIR *__dirp) __nonnull ((1));

DIR结构体定义

struct __dirstream   
{   
    void *__fd;    
    char *__data;    
    int __entry_data;    
    char *__ptr;    
    int __entry_ptr;    
    size_t __allocation;    
    size_t __size;    
    __libc_lock_define (, __lock)    
};   
typedef struct __dirstream DIR;  

 dirent结构体定义

struct dirent
{
    long d_ino;                     
    off_t d_off;                    
    unsigned short d_reclen;        
    char d_name [NAME_MAX+1];       
}

 1.2 应用代码

/**********************************************************************
* 文件名称: listFileNames.c
* 文件标识:无
* 内容摘要:对于给定的目录递归得到所有文件名
* 其它说明:无
**********************************************************************/
#include <string.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>

static DIR* dir;
#define _MAXPATH 1024
#define _MAXFILENAME 256
/****************************************************************
 * 功能描述: 获取指定路径下的文件名
 * 输入参数: dir-执行文件夹的对象
 *          
 * 输出参数: iFileName-一个文件的文件名
 * 返  回值: 0-执行成功    -1-执行失败
 * 其它说明:无
 ****************************************************************/
int getOneFileName(DIR *dir, char *iFileName)
{
    int ret = 0;
    struct dirent *ptr;

    if((ptr=readdir(dir)) != NULL)
    {
        if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)    // current dir OR parrent dir
            ret = getOneFileName(dir, iFileName);
        else if(ptr->d_type == 8)    /// file
        {
            strcpy(iFileName, ptr->d_name);
        }
    }
    else
    {
        ret = -1; //read end
    }
    return ret;
}

int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("Error. Enter an folder for list filename...\n");
        return 0;
    }

    char* pInputFolderPath = argv[1];
    char FileName[_MAXFILENAME] = {0};
    char FullPathName[_MAXPATH] = {0};
    if((dir = opendir(pInputFolderPath)) == NULL) // opendir
    {
        printf("Error. Failed to open folder ...");
        return 0;
    }
    while(getOneFileName(dir, FileName)==0)
    {
        snprintf(FullPathName,sizeof(FullPathName)-1, "%s/%s", pInputFolderPath, FileName);
        printf("FileName: %s\n", FullPathName);
    }

    return 0;
}

 编译

gcc listFileNames.c -o listFileNames

 运行

./listFileNames /home/nvidia

2. Windows环境下

2.1 windows下配置C++环境

参考链接: windows 10上使用vscode编译运行和调试C/C++ - 知乎 (zhihu.com)

  1. 下载mingw-w64

mingw系列编译器是非常好的并且主流的c/c++编译器,下载地址

        2. 解压,添加环境变量

        将mingw64位置的bin文件夹路径添加到环境变量中

C:\mingw64\bin

        3. 测试

        在Windows终端输入下述命令,测试gcc环境,打印的信息最后会得到gcc的版本信息。

 gcc -v

gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

  2.2 读取指定目录下所有文件名

在Windows下,遍历文件夹中所有文件,使用的是头文件《io.h》。

        1. 在遍历文件的时候,io.h中提供_finddata_t结构体来保存文件的信息

#define _finddata_t _finddata32_t
  struct _finddata32_t {
    unsigned attrib;            // 文件属性
    __time32_t time_create;     // 创建时间
    __time32_t time_access;     // 最近访问时间
    __time32_t time_write;      // 最近写入时间
    _fsize_t size;                // 文件大小
    char name[260];            // 文件名
  };

         2. 通过_findfirst、_findnext、_findclose来完成对文件夹的遍历,其中_findfirst和_findnext是宏定义,指向两个函数。

#define _findfirst _findfirst64i32
#define _findnext _findnext64i32

 _findfirst 的函数定义如下,功能是查找符合条件的第一个实例。

第一个参数:Filename是一个通配符

第二个参数:FindData用于存储当前查找到的文件信息

#ifndef __CRT__NO_INLINE
  __CRT_INLINE intptr_t __cdecl _findfirst64i32(const char *_Filename,struct _finddata64i32_t *_FindData)
  {
    struct __finddata64_t fd;
    intptr_t ret = _findfirst64(_Filename,&fd);
    if (ret == -1) {
      memset(_FindData,0,sizeof(struct _finddata64i32_t));
      return -1;
    }
    _FindData->attrib=fd.attrib;
    _FindData->time_create=fd.time_create;
    _FindData->time_access=fd.time_access;
    _FindData->time_write=fd.time_write;
    _FindData->size=(_fsize_t) fd.size;
    strncpy(_FindData->name,fd.name,260);
    return ret;
  }
#endif /* __CRT__NO_INLINE */

 返回值:如果查找成功则返回intptr_t类型的句柄,但是该句柄不是指针,而是int类型。 如果查找失败,则返回-1。

typedef int intptr_t;

_findnext 函数的功能是查找句柄中下一个符合条件的实例

第一个参数:FindHandle就是上述函数返回的句柄

第二个参数:FindData则是下一个句柄实例的文件信息

 返回值:查找失败返回-1,成功返回0.

#ifndef __CRT__NO_INLINE
  __CRT_INLINE int __cdecl _findnext64i32(intptr_t _FindHandle,struct _finddata64i32_t *_FindData)
  {
    struct __finddata64_t fd;
    int ret = _findnext64(_FindHandle,&fd);
    if (ret == -1) {
      memset(_FindData,0,sizeof(struct _finddata64i32_t));
      return -1;
    }
    _FindData->attrib=fd.attrib;
    _FindData->time_create=fd.time_create;
    _FindData->time_access=fd.time_access;
    _FindData->time_write=fd.time_write;
    _FindData->size=(_fsize_t) fd.size;
    strncpy(_FindData->name,fd.name,260);
    return ret;
  }
#endif /* __CRT__NO_INLINE */

_findclose函数的功能是关闭给定的句柄,成功返回0,失败返回-1.

  _CRTIMP int __cdecl _findclose(intptr_t _FindHandle);

2.3 应用代码

基于一个给定的目录路径,遍历打印内部的文件名。


#include <direct.h>
#include <io.h>
#include <stdio.h>

#define _MAXPATH 1024
#define _MAXFILENAME 256

int getOneFileName(char* pInputFolderPath, char* iFileName)
{
    int ret = 0;
    long handle = 0;
    struct _finddata_t fileInfo;
    char FullPathName[_MAXPATH] = {0};

    char szPath[_MAXPATH] = {0};
    memset(szPath, 0, sizeof(szPath));
    _snprintf(szPath, sizeof(szPath)-1, "%s\\*", pInputFolderPath);

    if ((handle=_findfirst(szPath, &fileInfo)) == -1) 
    {
        printf("Error. Failed to open folder ...");
        return 0;
    } 
    else
    {
        do{
            if (fileInfo.attrib &_A_SUBDIR) // 是目录
            {
                if (fileInfo.name[0] != '.') // 文件名不是'.'或'..'时
                {
                    memset(szPath, 0, sizeof(szPath));
                    _snprintf(szPath, sizeof(szPath)-1,"%s\\%s", pInputFolderPath, fileInfo.name);
                    printf("directory: %s\n", szPath);

                    ret = getOneFileName(szPath, iFileName);   // 继续遍历
                }
            }
            else    // 如果第一个实体不是目录,显示该文件
            {
                strcpy(iFileName, fileInfo.name);
                snprintf(FullPathName,sizeof(FullPathName)-1, "%s\\%s", pInputFolderPath, iFileName);
                printf("filename:%s\n", FullPathName);
            }
        }while (_findnext(handle, &fileInfo) == 0);
        
    }
    return ret;
}

int main(int argc, char* argv[])
{
    char* pInputFolderPath = ".";

    char szPath[_MAXPATH] = {0};
    memset(szPath, 0, sizeof(szPath));
    _snprintf(szPath, sizeof(szPath)-1, "%s\\*", pInputFolderPath);

    char FileName[_MAXFILENAME] = {0};
    char FullPathName[_MAXPATH] = {0};
    struct _finddata_t fileInfo;
    getOneFileName(pInputFolderPath, FileName);

    return 0;
}

参考链接: Windows下C++遍历文件夹中的文件 - 熊叫大雄 - 博客园 (cnblogs.com)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的C语言程序,以获取目录中最早的文件夹名称。程序中使用 opendir() 函数打开当前目录,然后使用 readdir() 函数遍历目录中的所有文件和文件夹,统计出文件夹的数目和最早的文件夹名称。 ```c #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> int main(){ DIR *dir; struct dirent *entry; struct stat statbuf; char *earliest_dir = NULL; // 打开目录 if((dir = opendir(".")) == NULL){ perror("opendir"); exit(1); } // 遍历目录中的文件和文件夹 while((entry = readdir(dir)) != NULL){ // 如果是文件夹 if(entry->d_type == DT_DIR){ // 排除 . 和 .. 目录 if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; // 获取文件夹信息 if(stat(entry->d_name, &statbuf) == -1){ perror("stat"); exit(1); } // 如果是最早的文件夹或者是第一个文件夹 if(earliest_dir == NULL || statbuf.st_mtime < stat(earliest_dir, &statbuf)){ earliest_dir = entry->d_name; } } } // 输出最早的文件夹名称 printf("目录中最早的文件夹名称为:%s\n", earliest_dir); // 关闭目录 closedir(dir); return 0; } ``` 程序通过 opendir() 函数打开当前目录,然后使用 readdir() 函数遍历目录中的所有文件和文件夹。对于每个文件夹,使用 stat() 函数获取文件夹的信息,如果是最早的文件夹或者是第一个文件夹,就将其名称保存在 earliest_dir 变量中。最后输出 earliest_dir 变量的值即为最早的文件夹名称。 需要注意的是,程序中使用了 dirent.h 和 sys/stat.h 头文件,需要链接对应的库文件。在 Linux 平台下,可以使用以下命令编译程序: ``` gcc -o earliest_dir earliest_dir.c -ldir ``` 在 Windows 平台下,可以使用以下命令编译程序: ``` gcc -o earliest_dir earliest_dir.c ``` 希望能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值