Linux内核编程 fork多进程文件拷贝操作

目录

一:练习

二:思路

三:实现

四:测试


一:练习

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终端运行程序

四个子文件拷贝成功,查看生成有副本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenruhan_QAQ_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值