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)
- 下载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;
}