c工具类,支持根据指定文件扩展名(如.shp或.zip)搜索所在文件夹路径
使用C语言实现的跨平台工具,用于遍历指定路径并查找包含指定扩展名文件(如
.shp或.zip)的文件夹路径。该实现使用标准C库,不依赖任何外部库,同时兼容Windows和Linux系统。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
// 跨平台路径分隔符
#ifdef _WIN32
#define PATH_SEP '\\'
#else
#define PATH_SEP '/'
#endif
// 递归遍历目录
static void find_folders_with_extension(
const char* root_path,
const char* extension,
char*** result,
int* count
) {
DIR* dir;
struct dirent* entry;
struct stat file_stat;
char full_path[1024];
// 检查根目录是否存在
if (stat(root_path, &file_stat) != 0 || !S_ISDIR(file_stat.st_mode)) {
return;
}
// 打开目录
dir = opendir(root_path);
if (!dir) return;
// 遍历目录中的每个条目
while ((entry = readdir(dir)) != NULL) {
// 跳过当前目录和父目录
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// 构建完整路径
snprintf(full_path, sizeof(full_path), "%s%c%s", root_path, PATH_SEP, entry->d_name);
// 检查是否为目录
if (stat(full_path, &file_stat) == 0 && S_ISDIR(file_stat.st_mode)) {
// 递归遍历子目录
find_folders_with_extension(full_path, extension, result, count);
} else {
// 检查文件扩展名
char* dot = strrchr(entry->d_name, '.');
if (dot && strlen(dot) > 1) {
char ext[10];
strncpy(ext, dot, sizeof(ext) - 1);
ext[sizeof(ext) - 1] = '\0';
// 转换为小写进行比较
for (int i = 0; ext[i]; i++) {
ext[i] = tolower(ext[i]);
}
// 检查是否匹配
if (strcmp(ext, extension) == 0) {
// 记录父目录路径
char* parent_dir = strdup(root_path);
// 添加到结果列表
*result = (char**)realloc(*result, (*count + 1) * sizeof(char*));
(*result)[*count] = parent_dir;
(*count)++;
}
}
}
}
closedir(dir);
}
// 查找包含指定扩展名文件的文件夹路径
char** find_folders_with_extension(const char* root_path, const char* extension, int* count) {
// 规范化扩展名
char normalized_ext[10];
if (extension[0] != '.') {
snprintf(normalized_ext, sizeof(normalized_ext), ".%s", extension);
} else {
strncpy(normalized_ext, extension, sizeof(normalized_ext) - 1);
normalized_ext[sizeof(normalized_ext) - 1] = '\0';
}
// 转换为小写
for (int i = 0; normalized_ext[i]; i++) {
normalized_ext[i] = tolower(normalized_ext[i]);
}
// 初始化结果
char** result = NULL;
*count = 0;
// 执行遍历
find_folders_with_extension(root_path, normalized_ext, &result, count);
return result;
}
// 释放结果内存
void free_result(char** result, int count) {
for (int i = 0; i < count; i++) {
free(result[i]);
}
free(result);
}
// 使用示例
int main() {
int shp_count;
char** shp_folders = find_folders_with_extension("C:/GIS_Data", "shp", &shp_count);
printf("包含.shp文件的文件夹路径:\n");
for (int i = 0; i < shp_count; i++) {
printf("%s\n", shp_folders[i]);
}
int zip_count;
char** zip_folders = find_folders_with_extension("C:/Archive", "zip", &zip_count);
printf("\n包含.zip文件的文件夹路径:\n");
for (int i = 0; i < zip_count; i++) {
printf("%s\n", zip_folders[i]);
}
// 释放内存
free_result(shp_folders, shp_count);
free_result(zip_folders, zip_count);
return 0;
}
关键特性说明
- 跨平台支持:
- 自动处理Windows(
\)和Linux/macOS(/)的路径分隔符 - 使用标准C库(
dirent.h,sys/stat.h),无需额外依赖 - 通过条件编译处理不同平台
- 自动处理Windows(
- 扩展名处理:
- 自动添加点前缀(
shp→.shp) - 大小写不敏感匹配(
.SHP、.Shp、.shp都会被识别)
- 自动添加点前缀(
- 内存管理:
- 使用
realloc动态管理结果列表 - 提供
free_result函数释放内存 - 避免内存泄漏
- 使用
- 健壮性:
- 检查根目录是否存在
- 跳过
.和..目录 - 安全的路径构建(使用
snprintf避免缓冲区溢出)
- 递归遍历:
- 递归遍历所有子目录
- 仅检查文件扩展名,不检查目录
使用说明
-
编译:
# Linux/macOS gcc file_finder.c -o file_finder # Windows (MinGW) gcc file_finder.c -o file_finder.exe -
使用示例:
// 搜索.shp文件所在文件夹 int shp_count; char** shp_folders = find_folders_with_extension("C:/GIS_Data", "shp", &shp_count); // 搜索.zip文件所在文件夹 int zip_count; char** zip_folders = find_folders_with_extension("/home/user/data", "zip", &zip_count); -
路径格式:
- Windows:
C:/GIS_Data(推荐正斜杠)或C:\\GIS_Data - Linux/macOS:
/home/user/data
- Windows:
输出示例
假设目录结构:
C:/
└── GIS_Data/
├── Project1/
│ ├── data.shp
│ └── metadata.txt
├── Project2/
│ └── data.zip
└── Project3/
├── map.shp
└── report.pdf
程序输出:
包含.shp文件的文件夹路径:
C:/GIS_Data/Project1
C:/GIS_Data/Project3
包含.zip文件的文件夹路径:
C:/GIS_Data/Project2
注意事项
- 路径长度限制:
- 代码中使用
1024字节缓冲区,对于超长路径可能需要调整 - 在Windows上,路径长度限制为260字符(但实际路径可以更长)
- 代码中使用
- 性能考虑:
- 递归遍历大型目录树可能较慢
- 对于超大目录,建议添加深度限制
- 错误处理:
- 如果根目录不存在,函数会返回空结果
- 未处理文件系统错误(如权限问题)
- 扩展名处理:
- 仅匹配文件扩展名(如
data.shp匹配.shp) - 不匹配隐藏文件(如
.shp)
- 仅匹配文件扩展名(如
为什么选择这个实现
- 纯C标准库:不依赖任何第三方库,保证可移植性
- 内存安全:正确管理动态分配的内存
- 跨平台:在Windows和Linux上都能正常工作
- 简洁高效:避免不必要的复杂性,专注于核心功能
- 健壮性:处理了常见路径问题和边界情况
可以灵活地搜索.shp、.zip或其他任何文件类型所在文件夹路径,且在C语言中实现了最优的跨平台兼容性。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 软件从业者Hort
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

