目录
一:练习
1.程序运行给定一个文件夹路径(例如:该文件夹下有四个文件)
2.通过opendir和readdir操作获取该文件夹下的链接,判断是子文件夹还是子文件
3.对子文件夹直接跳过,如果是子文件则fork一个子进程来完成该文件的拷贝操作
二:思路
主要流程:
三:实现
#include<iostream>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
void CopyFile(string path)
{
//pid_t,int数据类型都可以
int pid = 0;
//此结构体下d_name-文件(文件夹)名
struct dirent* dir_ent;
DIR* dir;
//用来保存一个路径信息
struct stat s_buf;
//获取路径,把信息存入struct stat s_buf
//c_str:string类型转换为char*类型
stat(path.c_str(), &s_buf);
//Linux内核中宏定义函数
//S_ISDIR 是文件夹返回1
//S_ISREG 是文件返回1
//st_mode可以判断当前的是一个文件夹还是一个文件
cout << "S_ISDIR = " << S_ISDIR(s_buf.st_mode) << endl;
//如果是文件夹
if (S_ISDIR(s_buf.st_mode) == 1)
{
if ((dir = opendir(path.c_str())) == NULL)
{
perror("open dir error");
}
else {
//需要有完整的路径给到open,才能打开文件,再进行读 写操作
//filepath保存完整拼接路径
char filepath[200] = { 0 };
while ((dir_ent = readdir(dir)) != NULL)
{
//初始化操作
bzero(filepath, sizeof(filepath));
//文件名和文件夹路径进行字符串的拼接-->完整路径
strcat(filepath, path.c_str());
strcat(filepath, "/");
//d_name文件名
strcat(filepath, dir_ent->d_name);
//stat判断文件还是文件夹
stat(filepath, &s_buf);
//如果是子文件夹,continux跳过
if (S_ISDIR(s_buf.st_mode) == 1)
{
continue;
}
//是子文件,可以拷贝操作
else if (S_ISREG(s_buf.st_mode) == 1)
{
pid = fork();
//子进程
if (pid == 0)
{
//拷贝开始
int fromFd = 0;
//拷贝结束
int toFd = 0;
int res = 0;
char buf[1024] = { 0 };
//拷贝的文件需要创建,创建出来的文件需要修改权限
umask(0);
//可读,读取
fromFd = open(filepath, O_RDONLY, 0777);
//拷贝结果路径
strcat(filepath, "副本");
//open 写方式创建
toFd = open(filepath, O_CREAT | O_WRONLY, 0777);
if (fromFd < 0 || toFd < 0)
{
perror("open file error");
}
else {
cout << "当前子进程 pid = " << getpid() << "开始拷贝" << endl;
while ((res = read(fromFd, buf, sizeof(buf))) > 0)
{
//res读多少就写多少
write(toFd, buf, res);
//清空操作
bzero(buf, sizeof(buf));
}
cout << "当前子进程 pid = " << getpid() << "拷贝成功" << endl;
//先关读
close(fromFd);
//后关写
close(toFd);
}
//子进程退出循环
_exit(0);
}
}
}
//死循环不让父进程先于子进程结束 避免出现孤儿进程
while (1) {}//waitpid(pid,&status,NULL);
}
}
//不是文件夹,给出提示
else {
cout << "当前路径不正确,不是一个文件夹" << endl;
}
}
int main()
{
CopyFile("/root/3");
return 0;
}
四:测试
在主文件夹下的名称3的文件夹下,有2个子文件夹,4个子文件,
要求对子文件夹不操作,对4个子文件进程拷贝操作
ubuntu终端运行程序
四个子文件拷贝成功,查看生成有副本