#创作灵感#
- 能有啥灵感啊,无非就是找不到现成代码没法摸鱼了;
- 然后一个月前应该交的实验报告因为反正都迟交了,
- 重度 ddl 拖延症患者决定把 lab6-9 的实验报告堆在一起交了;
- 刚水完实验报告,顺便传一份。
文档我就懒得粘贴了,概括就几个字——
多进程拷贝目录
代码思想(非老师期望的运行方式,非生产者消费者逻辑!!!)
- 创建主进程,遍历根目录——
- 如果遇到文件夹,则创建这个空文件夹,并将路径传递给子进程,让子进程遍历子目录去;
- 如果遇到文件,则直接进行拷贝;
- 处理完次层的所有文件(文件夹)直接退出释放资源。
这个方法是“爆炸式增长的”,且不会造成任何的冲突等情况,唯一可能遇到的问题是——
要拷贝的文件太多了,电脑直接死机。
但你就说快不快吧。
- 因为无法直接使用time获取时间,可以通过每个进程都输出log,用最后一个的创建时间减去第一个的创建时间即可得出最终数据。
实验结果
哥们自己跑一下吧,实在不行让GPT编一下吧
源代码
注意:在代码中,我仅判断了read的文件是不是文件夹,也就是说如有一些引用文件夹等其他形式的文件夹会被认为是空文件,但是这个其实加一个判断就对了,在本次实验中已经圆满完成了练习目的,就不加了。(说白了就是懒)
然后哥们,记得把路径改一下,内核中的学号别也给我搞去了
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
int main (int argc, char *argv[])
{
printf("yy: start working\n");
for (int i = 0; i < argc; i++) {
printf("yy: now argv[%d] is %s\n", i, argv[i]);
}
// printf("yy: now src %s\n", argv[1]);
// printf("yy: now dis %s\n", argv[2]);
char *input = argv[1];
char output[128]; // 假设输出的字符串不超过100个字符
for (int i = 0; input[i] != '\0'; i++) {
if (input[i] == '/') {
output[i] = '_';
} else {
output[i] = input[i];
}
}
output[strlen(input)] = '\0'; // 添加字符串结尾标识
// 保存原始的stdout
int orig_stdout = dup(fileno(stdout));
// 创建文件名为yuanmulu的文件
char filename[128];
snprintf(filename, 128, "./log/%d_%s.log", getpid(), output);
freopen(filename, "w", stdout);
DIR *dir;
struct dirent *entry;
dir = opendir(argv[1]);
while ((entry = readdir(dir)) != NULL) {
char * name = entry->d_name;
printf("yy: now open %s\n", name);
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
printf("yy: now skip %s\n", name);
continue;
}
char src[256];
snprintf(src, sizeof(src), "%s/%s", argv[1], name);
printf("yy: now contact src: %s\n", src);
char dis[256];
snprintf(dis, sizeof(dis), "%s/%s", argv[2], name);
printf("yy: now contact dis: %s && create this folder\n", dis);
if (entry->d_type == DT_DIR) {
printf("File: %s\n", name);
if (mkdir(dis, 0777) == -1) {
perror("Error creating subfolder");
}
pid_t pid = fork();
if (pid == 0) {
printf("yy: child Process is working...\n");
execlp("/home/YourNameandId/桌面/lab6/main", "./main", src, dis, NULL);
fprintf(stderr, "it's imposible\n");
return 1;
}
else if (pid < 0) {
fprintf(stderr, "Fork Failed\n");
// return 1;
}
else {
printf ("yy: now back to Parent\n");
}
}
else {
printf("yy: parent direct copy file\n");
FILE *sourceFile, *destinationFile;
char ch;
// 打开源文件
sourceFile = fopen(src, "r");
if (sourceFile == NULL) {
perror("Error opening source file");
return -1;
}
// 创建并打开目标文件
destinationFile = fopen(dis, "w");
if (destinationFile == NULL) {
perror("Error creating destination file");
fclose(sourceFile);
return -1;
}
// 从源文件读取内容并写入目标文件
while ((ch = fgetc(sourceFile)) != EOF) {
fputc(ch, destinationFile);
}
// 关闭文件
fclose(sourceFile);
fclose(destinationFile);
printf("yy: 文件拷贝成功\n");
}
// 关闭文件
fclose(stdout);
// 恢复标准输出到控制台
dup2(orig_stdout, fileno(stdout));
close(orig_stdout);
}
return 0;
}