使用 readdir 函数来实现目录备份,通常涉及遍历源目录中的所有文件和子目录,并将它们复制到目标位置。以下是一个使用 C 语言编写的示例程序,演示如何使用 readdir 实现目录备份:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
// 函数声明
int copy_file(const char *src, const char *dest);
int copy_directory(const char *src, const char *dest);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "用法: %s <源目录> <目标目录>\n", argv[0]);
return EXIT_FAILURE;
}
const char *source = argv[1];
const char *destination = argv[2];
// 检查源目录是否存在
struct stat st;
if (stat(source, &st) != 0) {
perror("无法获取源目录信息");
return EXIT_FAILURE;
}
if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "源路径不是一个目录: %s\n", source);
return EXIT_FAILURE;
}
// 创建目标目录(如果不存在)
if (mkdir(destination, st.st_mode) != 0 && errno != EEXIST) {
perror("无法创建目标目录");
return EXIT_FAILURE;
}
// 复制目录内容
if (copy_directory(source, destination) != 0) {
fprintf(stderr, "目录备份失败\n");
return EXIT_FAILURE;
}
printf("目录备份成功: %s 到 %s\n", source, destination);
return EXIT_SUCCESS;
}
// 复制单个文件
int copy_file(const char *src, const char *dest) {
FILE *sf = fopen(src, "rb");
if (!sf) {
perror("无法打开源文件");
return EXIT_FAILURE;
}
FILE *df = fopen(dest, "wb");
if (!df) {
perror("无法打开目标文件");
fclose(sf);
return EXIT_FAILURE;
}
size_t bytes_read;
char buffer[4096];
while ((bytes_read = fread(buffer, 1, sizeof(buffer), sf)) > 0) {
if (fwrite(buffer, 1, bytes_read, df) != bytes_read) {
perror("写入目标文件时出错");
fclose(sf);
fclose(df);
return EXIT_FAILURE;
}
}
fclose(sf);
fclose(df);
return EXIT_SUCCESS;
}
// 递归复制目录
int copy_directory(const char *src, const char *dest) {
DIR *dir = opendir(src);
if (!dir) {
perror("无法打开目录");
return EXIT_FAILURE;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue; // 跳过当前目录和父目录
char src_path[PATH_MAX];
char dest_path[PATH_MAX];
snprintf(src_path, sizeof(src_path), "%s/%s", src, entry->d_name);
snprintf(dest_path, sizeof(dest_path), "%s/%s", dest, entry->d_name);
struct stat st;
if (stat(src_path, &st) != 0) {
perror("无法获取文件/目录信息");
closedir(dir);
return EXIT_FAILURE;
}
if (S_ISDIR(st.st_mode)) {
// 如果是目录,递归复制
if (mkdir(dest_path, st.st_mode) != 0 && errno != EEXIST) {
perror("无法创建目标子目录");
closedir(dir);
return EXIT_FAILURE;
}
if (copy_directory(src_path, dest_path) != 0) {
closedir(dir);
return EXIT_FAILURE;
}
} else {
// 如果是文件,直接复制
if (copy_file(src_path, dest_path) != 0) {
closedir(dir);
return EXIT_FAILURE;
}
}
}
closedir(dir);
return EXIT_SUCCESS;
}
参数检查:
stat 函数检查源路径是否为目录。创建目标目录:
mkdir 创建目标目录,如果已存在则忽略错误(EEXIST)。复制目录内容:
opendir 和 readdir 遍历源目录中的所有条目。copy_file 函数进行复制。copy_directory 进行复制。复制文件:
fopen、fread、fwrite 和 fclose 逐块读取并写入文件内容。错误处理:
保存上述代码到一个文件,例如 backup.c,然后使用以下命令编译:
gcc -o backup backup.c
运行程序时提供源目录和目标目录作为参数:
./backup /path/to/source /path/to/destination
copy_directory 中添加相应的逻辑。通过以上步骤,你可以使用 readdir 函数实现基本的目录备份功能。根据具体需求,你还可以扩展该程序以支持更多功能,如增量备份、日志记录、并行复制等。