有时候需要获取一个文件夹下的所有文件,甚至需要获取特定类型的文件。下面介绍两种分别在 Linux 和 Windows下可以运行的程序实现。
Linux C
在 Linux 中可以使用 opendir,readdir,closedir 来实现.
函数原型:
int alphasort(const struct dirent **, const struct dirent **);
int closedir(DIR *);
int dirfd(DIR *);
DIR *fdopendir(int);
DIR *opendir(const char *);
struct dirent *readdir(DIR *);
int readdir_r(DIR *restrict, struct dirent *restrict,
struct dirent **restrict);
void rewinddir(DIR *);
int scandir(const char *, struct dirent ***,
int (*)(const struct dirent *),
int (*)(const struct dirent **,
const struct dirent **));
这些函数都在 dirent.h 头文件中,为了使用这些函数,还需要一个特别重要的结构体 dirent:
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
主要会用到 d_type 和 d_name,分别表示文件的类型和文件名。
d_type 有这几种可能的值:
DT_BLK This is a block device.
DT_CHR This is a character device.
DT_DIR This is a directory.
DT_FIFO This is a named pipe (FIFO).
DT_LNK This is a symbolic link.
DT_REG This is a regular file.
DT_SOCK This is a UNIX domain socket.
DT_UNKNOWN The file type could not be determined.
DIR应该和FILE类似。就不多说了。我们只需要知道opendir失败时会返回NULL就够了。
code
#include <stdio.h>
#include <dirent.h>
#include <string.h>
void findDir(char* path){
DIR *dir = opendir(path);
if(dir == NULL){
printf("open path fail: %s \n", path);
return;
}
struct dirent* ent = NULL;
while (NULL != (ent = readdir(dir)))
{
if (ent->d_type == DT_REG)
{
printf("normal: %s \n", ent->d_name);
}
else if(ent->d_type == DT_DIR)
{
printf("subdir: %s \n", ent->d_name);
if( 0!=strcmp(ent->d_name, ".") && 0!=strcmp(ent->d_name, "..") ){
findDir(ent->d_name);
printf("end %s \n", ent->d_name);
}
}
}
}
int main(int argc, char * argv[])
{
char* path = ".";
findDir(path);
return 0;
}
Windows C++
code
#include<iostream>
#include<io.h>
#include<string>
using namespace std;
string respath = "*.*";
void displayFile(string path) {
string st{path + respath};
std::cout << path << std::endl;
_finddata_t file;
intptr_t lf;
if ((lf = _findfirst(st.c_str(), &file)) == -1)
cout << "can not find any file!" << std::endl;
else {
cout << "file lists:" << std::endl;
do {
string str{file.name};
std::cout << file.name << std::endl;
if (file.attrib == _A_NORMAL)cout << " normal " << std::endl;
else if (file.attrib == _A_RDONLY)cout << " read only " << std::endl;
else if (file.attrib == _A_HIDDEN)cout << " hidden " << std::endl;
else if (file.attrib == _A_SYSTEM)cout << " system " << std::endl;
else if (file.attrib == _A_SUBDIR) {
if (strcmp(file.name, ".") == 0 ||
strcmp(file.name, "..") == 0 ||
strcmp(file.name, ".svn") == 0 ||
strcmp(file.name, ".git") == 0) {
std::cout << "ignore " << file.name << std::endl;
} else {
cout << " subdir " << file.name << endl;
string temp{path + file.name + "/"};
// recursion
displayFile(temp);
temp = path;
}
}
} while (_findnext(lf, &file) == 0);
}
_findclose(lf);
}
int main() {
string path = "D:/images/desk/";
//_finddata_t file;
displayFile(path);
return 0;
}