/*
* 模块功能:
* 1、读取目录中的文件路径。
* 2、递归获取目录、文件的路径信息。
* 3、获取文件信息,包括文件的类型(目录、普通文件等)、文件大小、文件的时间属性(创建时间、修改时间、访问时间)等。
* 4、将time_t类型的时间转换为字符串。
*
* 修改时间:2022-09-27
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <dirent.h>
#include <time.h>
#include "readdir.h"
// 两个整型数的最大值、最小值
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
/********************* 目录文件读取 *********************/
/**
* @brief init_head_node 初始化头节点
* @return 头节点指针(动态分配的堆内存空间,后续需要调用free_memory()函数释放)
*/
pathInfo *init_head_node()
{
pathInfo *head_info = (pathInfo *)malloc(sizeof(pathInfo));
if(!head_info) {
return NULL;
}
head_info->pre = NULL;
head_info->next = NULL;
//printf("%p\n", head_info);
return head_info;
}
/**
* @brief free_memory 释放内存,模块函数调用动态申请的堆内存
* @param path_info 链表头节点
*/
void free_memory(pathInfo *path_info)
{
if(!path_info) {
return;
}
pathInfo *info = path_info;
pathInfo *info1;
while(info) {
info1 = info->next;
info->pre = NULL;
info->next = NULL;
//printf("%s : free_memory = %p\n", __FUNCTION__, info);
free(info);
info = info1;
}
}
/**
* @brief read_dir 获取目录中的文件夹和文件的名字,只读取一级目录
* @param dir_path 需要读取的目录
* @param path_info 读取返回的信息头节点,头节点存储用户输入的目录信息,读取到的信息通过内部的指针next偏移读取
* @return 0:成功 -1:失败,非法参数 -2:目录打开失败 -3:获取文件信息失败
* 注:读取返回的信息是文件夹和文件的名字。
*/
int read_dir(const char *dir_path, pathInfo *path_info)
{
DIR *dir = NULL;
struct dirent *entry;
struct stat sta;
char path[PATH_LENGTH];
pathInfo *pre = NULL, *last = NULL;
int ret_val = 0;
if(!dir_path || !path_info) {
return -1;
}
dir = opendir(dir_path);
if(dir == NULL) {
return -2;
}
// 头节点存储用户输入的目录信息
path_info->pre = NULL;
path_info->next = NULL;
path_info->isdir = true;
memset(path_info->name, 0, sizeof(path_info->name));
memcpy(path_info->name, dir_path, MIN(strlen(dir_path), PATH_LENGTH - 1));
while(1) {
entry = readdir(dir);
if(entry == NULL) {
break;
}
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
memset(path, 0, sizeof(path));
strcpy(path, dir_path);
if(path[strlen(path) - 1] != '/') {
strcat(path, "/");
}
strcat(path, entry->d_name);
if(stat(path, &sta) < 0) {
ret_val = -3;
break;
}
if(last) {
pre = last;
}
last = (pathInfo *)malloc(sizeof(pathInfo));
//printf("%s : malloc_memory = %p\n", __FUNCTION__, last);
if(S_ISDIR(sta.st_mode)) {
last->isdir = true;
}
else {
last->isdir = false;
}
last->pre = pre;
last->next = NULL;
memset(last->name, 0, PATH_LENGTH);
memcpy(last->name, entry->d_name, MIN(strlen(entry->d_name), PATH_LENGTH - 1));
path_info->pre = last;
if(pre) {
pre->next = last;
}
else {
path_info->next = last;
}
}
closedir(dir);
return ret_val;
}
/**
* @brief read_dir_ex 获取目录中的文件夹和文件的路径,只读取一级目录
* @param dir_path 需要读取的目录
* @param path_info 读取返回的信息头节点,头节点存储用户输入的目录信息,读取到的信息通过内部的指针next偏移读取
* @return 0:成功 -1:失败,非法参数 -2:目录打开失败 -3:获取文件信息失败
* 注:读取返回的信息是文件夹和文件的完整路径。
*/
int read_dir_ex(const char *dir_path, pathInfo *path_info)
{
DIR *dir = NULL;
struct dirent *entry;
struct stat sta;
char path[PATH_LENGTH];
pathInfo *pre = NULL, *last = NULL;
int ret_val = 0;
if(!dir_path || !path_info) {
return -1;
}
dir = opendir(dir_path);
if(dir == NULL) {
return -2;
}
// 头节点存储用户输入的目录信息
path_info->pre = NULL;
path_info->next = NULL;
path_info->isdir = true;
memset(path_info->name, 0, sizeof(path_info->name));
memcpy(path_info->name, dir_path, MIN(strlen(dir_path), PATH_LENGTH - 1));
while(1) {
entry = readdir(dir);
if(entry == NULL) {
break;
}
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
memset(path, 0, sizeof(path));
strcpy(path, dir_path);
if(path[strlen(path) - 1] != '/') {
strcat(path, "/");
}
strcat(path, entry->d_name);
if(stat(path, &sta) < 0) {
ret_val = -3;
break;
}
if(last) {
pre = last;
}
last = (pathInfo *)malloc(sizeof(pathInfo));
//printf("%s : malloc_memory = %p\n", __FUNCTION__, last);
if(S_ISDIR(sta.st_mode)) {
last->isdir = true;
}
else {
last->isdir = false;
}
last->pre = pre;
last->next = NULL;
memset(last->name, 0, PATH_LENGTH);
memcpy(last->name, path, MIN(strlen(path), PATH_LENGTH - 1));
path_info->pre = last;
if(pre) {
pre->next = last;
}
else {
path_info->next = last;
}
}
closedir(dir);
return ret_val;
}
/**
* @brief read_file_path 获取目录中所有的文件路径,递归读取
* @param dir_path 需要读取的目录
* @param path_info 读取返回的信息头节点,头节点存储用户输入的目录信息,读取到的信息通过内部的指针next偏移读取
* @return 0:成功 -1:失败,非法参数 -2:目录打开失败 -3:获取文件信息失败
* 注:读取返回的只是文件的路径,不包含空文件夹
*/
int read_file_path(const char *dir_path, pathInfo *path_info)
{
int ret_val;
pathInfo info, *info2, info3, *info4;
pathInfo *pre = NULL, *last = NULL;
if(!dir_path || !path_info) {
return -1;
}
// 头节点存储用户输入的目录信息
path_info->pre = NULL;
path_info->next = NULL;
path_info->isdir = true;
memset(path_info->name, 0, sizeof(path_info->name));
memcpy(path_info->name, dir_path, MIN(strlen(dir_path), PATH_LENGTH - 1));
ret_val = read_dir_ex(dir_path, &info);
if(ret_val == 0) {
info2 = info.next;
while(info2) {
if(last) {
pre = last; // 后续继续追加链表数据,在这里记录一下最后一个节点
}
if(info2->isdir) {
ret_val = read_file_path(info2->name, &info3);
if(ret_val != 0) {
break;
}

叶落花枯
- 粉丝: 1w+
最新资源
- 翻译网站大全-爱翻译的娃一定要收藏哦(1).doc
- 基于opencv的银行卡号识别学士学位论文(1).doc
- 计算机组成原理本全(1).ppt
- 计算机专业技能训练教学管理制度(1).doc
- 人形机器人的国内外研究现状及发展趋势-自动化导论论文(1)(1).docx
- Unit1-Knowing-me--knowing-you—Developing-ideas教学设计(1).docx
- 小学计算机教学工作总结3篇(1).docx
- 计算机实习报告心得(1).docx
- 《计算机司法检验学》教学辅助系统的设计与实现(1).docx
- 2023年单片机原理及应用期末考试必考知识点重点总结(1).doc
- 铁路工程信息化管理措施(1).docx
- 基于at89c51单片机的大棚环境测控系统本科学位论文(1).doc
- 计算机公司大学生实习报告-(1).docx
- 信息化管理规划方案(1)(1).doc
- 完整版第二季金税三期客户端软件培训直播笔记(老会计人的经验)(1)(1).doc
- 探讨大数据时代下的英语教学新模式(1).docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



评论5