将多文件夹中的JPG图片合并复制到单个文件夹的技术需求
批量复制嵌套文件夹中JPG图片到目标文件夹的C语言实现
嘿,我看你已经着手写C代码处理嵌套文件夹里的JPG批量复制了,刚好我之前做过类似需求,给你完善好完整的可运行实现,还会拆解关键逻辑,方便你理解~
#include <stdio.h> #include <dirent.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #include <unistd.h> // 复制单个文件的核心函数 int copy_file(const char *src_path, const char *dest_path) { FILE *src = fopen(src_path, "rb"); if (!src) { perror("无法打开源文件"); return -1; } FILE *dest = fopen(dest_path, "wb"); if (!dest) { perror("无法打开目标文件"); fclose(src); return -1; } // 用4KB缓冲区提升读写效率 char buffer[4096]; size_t bytes_read; while ((bytes_read = fread(buffer, 1, sizeof(buffer), src)) > 0) { if (fwrite(buffer, 1, bytes_read, dest) != bytes_read) { perror("写入目标文件失败"); fclose(src); fclose(dest); return -1; } } if (ferror(src)) { perror("读取源文件失败"); fclose(src); fclose(dest); return -1; } fclose(src); fclose(dest); return 0; } // 递归遍历目录,处理所有子文件夹 void traverse_directory(const char *dir_path, const char *dest_dir) { DIR *dir = opendir(dir_path); if (!dir) { perror("无法打开目录"); return; } struct dirent *entry; while ((entry = readdir(dir)) != NULL) { // 跳过当前目录(.)和上级目录(..),避免无限递归 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } // 拼接当前文件/子目录的完整路径 char full_path[1024]; snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name); // 获取文件属性,区分目录和普通文件 struct stat stat_buf; if (stat(full_path, &stat_buf) == -1) { perror("获取文件属性失败"); continue; } if (S_ISDIR(stat_buf.st_mode)) { // 如果是子目录,递归进去继续处理 traverse_directory(full_path, dest_dir); } else { // 检查是否是JPG文件(兼容大小写后缀) char *ext = strrchr(entry->d_name, '.'); if (ext != NULL && (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".JPG") == 0)) { // 处理文件名重复:自动添加数字后缀避免覆盖 char dest_path[1024]; int suffix = 0; while (1) { if (suffix == 0) { snprintf(dest_path, sizeof(dest_path), "%s/%s", dest_dir, entry->d_name); } else { char base_name[512]; strncpy(base_name, entry->d_name, ext - entry->d_name); base_name[ext - entry->d_name] = '\0'; snprintf(dest_path, sizeof(dest_path), "%s/%s_%d.jpg", dest_dir, base_name, suffix); } // 检查目标文件是否存在,不存在就用这个路径 if (access(dest_path, F_OK) == -1) { break; } suffix++; } // 执行复制并打印日志 if (copy_file(full_path, dest_path) == 0) { printf("已复制: %s -> %s\n", full_path, dest_path); } } } } closedir(dir); } // 确保目标文件夹存在,不存在则创建 int create_directory(const char *dir_path) { struct stat stat_buf; if (stat(dir_path, &stat_buf) == -1) { // 目录不存在,创建它(权限设为0755,通用可读可执行) if (mkdir(dir_path, 0755) == -1) { perror("创建目标文件夹失败"); return -1; } } else if (!S_ISDIR(stat_buf.st_mode)) { fprintf(stderr, "错误:%s 不是一个目录\n", dir_path); return -1; } return 0; } int main(int argc, char *argv[]) { // 检查命令行参数是否正确 if (argc != 3) { fprintf(stderr, "使用方法:%s <源父文件夹路径> <目标文件夹路径>\n", argv[0]); return EXIT_FAILURE; } const char *src_dir = argv[1]; const char *dest_dir = argv[2]; // 先创建目标文件夹(如果需要) if (create_directory(dest_dir) == -1) { return EXIT_FAILURE; } // 开始遍历源目录处理所有JPG traverse_directory(src_dir, dest_dir); printf("复制完成!\n"); return EXIT_SUCCESS; }
关键逻辑说明
- 递归目录遍历:
traverse_directory函数会自动进入每个子文件夹,跳过特殊目录避免死循环; - 高效文件复制:用4KB缓冲区读写,比单字节读写效率提升明显;
- 重复文件名处理:自动添加
_1、_2这类后缀,不用担心覆盖目标文件夹里的原有文件; - 兼容性处理:同时识别
.jpg和.JPG后缀,你可以自行添加.jpeg等其他格式的判断; - 错误处理:每一步操作都加了错误提示,方便排查问题。
使用方法
- 编译代码:
gcc -o copy_jpgs copy_jpgs.c
- 运行程序(替换成你的实际路径):
./copy_jpgs ./2018 ./all_jpgs
内容的提问来源于stack exchange,提问作者AHF
相关产品推荐
相关产品推荐

