参考资料:
C语言遍历文件夹
首先首先根据参考资料中文章理解遍历文件夹的方法。
#include <stdio.h>
#include <string.h>
#include <dirent.h>
void myfilerecursive(char *path);
int main()
{
// 文件夹名称
char name[100000] = "D:\\test";
// printf("Enter path to list files: ");
// scanf("%s", name);
myfilerecursive(name);
return 0;
}
void myfilerecursive(char *basePath)
{
// 路径
char path[1000];
struct dirent *dp;
DIR *dir = opendir(basePath);
// 如果是文件则直接结束此次调用
if (!dir) {
return;
}
while ((dp = readdir(dir)) != NULL)
{
// 跳过 "." 和 ”..“
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
// 将文件名和路径进行拼接形成一个完整路径
printf("%s\n", dp->d_name);
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
// 递归遍历
myfilerecursive(path);
}
}
closedir(dir);
}
这是 结构体 dirent 的结构,通过访问这个结构体中数据可以获取文件名
进阶
题目描述:
遍历一个文件夹,将遍历得到的信息(文件名、文件类型、文件大小等)保存至结构体中,然后再把结构体中的信息保存至一个文件中。
代码:
对于代码的理解请看注释
#include <stdio.h>
#include <string.h>
#include <dirent.h>
void myfilerecursive(char *path, struct FILE_STR *fileStrs);
int get_file_size(char *filePath);
char* get_suffix(char* dest, char* filename);
char *right(char *dest, char *src, int n);
// 文件信息结构体
// 注意:结构中应当使用数组而不是指针,否则写入文件时无法正确获取指针的结束位
typedef struct FILE_STR{
char filename[100]; // 文件名
char fileType[10]; // 文件类型(文件夹或文件)
int fileSize; // 文件大小
char suffix[10]; // 文件后缀
} file_str;
// 全局变量,记录结构体数量(或者使用指针作为参数代替)
int count = 0;
int main() {
char name[10000];
// printf("Enter path to list files: ");
// scanf("%s", name);
// myfilerecursive(name);
char basePath[100] = "F:\\tmp";
file_str fileStrs[100];
// 递归遍历文件夹,并将信息保存至结构体数组中
myfilerecursive(basePath, fileStrs);
// 定义一个文件指针
FILE *fp ;
// 打开文件,没有文件自动创建
if((fp=fopen("files.txt","w"))==NULL) {
perror("fopen");
printf("====error====");
}
int i = 0;
// 将结构体数组中的信息保存至文件中
while (i < count){
// 写入数据至文件中 (注意:如果其他步骤除了问题(虽然没有报错),这一步基本也不会成功,可以把这个放在循环外,看看是否有问题)
fprintf(fp,"filename:%s \tfileType:%s \tfileSize:%d \tsuffix:%s\n", fileStrs[i].filename,
fileStrs[i].fileType, fileStrs[i].fileSize, fileStrs[i].suffix);
i++;
}
// 必须要关闭,否则内容不会写入文件中
fclose(fp);
return 0;
}
void myfilerecursive(char *basePath, file_str *fileStrs) {
// path 作为一个目录,记录当前访问的目录
char path[1000];
// 定义结构体数组(指针)
struct dirent *dp;
DIR *dir = opendir(basePath);
// if (!dir) {
// return;
// }
// 以上写法等同于
if (dir == NULL) {
// 如果该路径(path)不可读,则直接结束此次方法调用
return;
}
while ((dp = readdir(dir)) != NULL) {
// 不读取 "." 和 ".."
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
{
// 定义结构体
file_str fileStr;
strcpy(fileStr.filename, dp->d_name); // fileStr.filename = dp->d_name; 指针写法在将信息写入文件时有问题
// 复制 basePath 至 path
strcpy(path, basePath);
// 将 / 追加到 path 中,拼接为一个目录
strcat(path, "/");
// 将文件名或目录名(d_name)追加到 path 中
strcat(path, dp->d_name);
// 判断是否是文件夹
DIR *isDir = opendir(path);
int size = get_file_size(path);
if (isDir != NULL) {
// warning: ISO C++ forbids converting a string constant to 'char*'
char tmp[10] = "文件夹";
strcpy(fileStr.fileType, tmp); // fileStr.fileType = tmp;
} else {
fileStr.fileSize = size;
char tmp[10] = "文件";
strcpy(fileStr.fileType, tmp); // fileStr.fileType = tmp;
char suf[10];
get_suffix(suf, dp->d_name);
strcpy(fileStr.suffix, suf); // fileStr.suffix = suf;
}
// fileStr.filename = dp->d_name;
fileStrs[count++] = fileStr;
// 递归调用
myfilerecursive(path, fileStrs);
}
}
closedir(dir);
}
// 获取文件大小
int get_file_size(char* filePath)
{
FILE *fp=fopen(filePath,"r");
if(!fp) {
return -1;
}
fseek(fp,0L,SEEK_END);
int size=ftell(fp);
fclose(fp);
return size;
}
// 获取文件名后缀
char* get_suffix(char* dest, char* filename) {
// 注意:strlen()函数得到英文和中文字符的长度不一样
int len = strlen(filename);
int i;
for (i = len - 1; i >= 0; i--) {
// 最后一次出现字符 '.' 的位置
if (filename[i] == '.') {
right(dest, filename, len - i - 1);
break;
}
}
return dest;
}
// 从右边开始截取指定数量字符串
char *right(char *dest, char *src, int n) {
char *p = dest;
char *q = src;
int len = strlen(src);
if (n > len) {
n = len;
}
//int start=len-n;
//q=q+start;
q += len - n;
while (n--) {
*(p++) = *(q++);
}
*(p++) = '\0';
return dest;
}
遍历文件夹的目录结构:
最终保存文件结果:
版权声明:本文为qq_38431321原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。