要求:
- 通过父子进程完成对文件的拷贝(cp),父进程从文件开始到文件的一半开始拷贝,子进程从文件的一半到文件末尾。要求:文件IO cp src dest
- 文件长度获取?lseek
- 子进程定位到文件一半的位置 lseek
- 父进程怎么能准确读到文件一半的位置
- fork之前打开文件,父子进程中读写文件时,位置指针是同一个
步骤:
1.打开进行操作的文件,
被复制的文件只读打开,
目标文件可写打开,不存在就创建,
2.创建子进程,并判断是否创成功
3.子进程中,定位到文件中间,
读取文件的字符暂存在缓存区中,
把读取到的字符写入到目标文件的后一半
4.父进程中,定位到文件首位,
从首位置到文件中间位置的字符读入到缓存区中,
把读取的字符写入到目标文件的前半段
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
// 判断是否输入了两个操作的文件夹
if (argc != 3)
{
printf("format err");
return -1;
}
// 只读打开被复制的文件
// 打开复制的目标文件,可写,不存在创建,存在清空
int fd_src = open(argv[1], O_RDONLY);
int fd_dest = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0777);
// 返回最后一位位置,得到字符个数
int num = lseek(fd_src, 0, SEEK_END);
__pid_t pid = fork(); // 创建子进程
if (pid < 0)
{
perror("fork err");
return -1;
}
else if (pid == 0) // 子进程 // 从后一半写入
{
char s[99];
// 定位到中间
lseek(fd_src, num / 2, SEEK_SET);
lseek(fd_dest, num / 2, SEEK_SET);
int d;
// 读取文件一的字符,保存在s中 返回值得到实际读取的字符个数
while ((d = read(fd_src, s, 99)) > 0)
{
// 把s中的d个字符写入到第二个文件中
write(fd_dest, s, d);
sleep(1); // 每次读入
}
}
else // 父进程
{
// 阻塞,等待子进程复制完后半段
wait(NULL);
// 暂存
char c[32];
// 定位到首位
lseek(fd_src, 0, SEEK_SET);
lseek(fd_dest, 0, SEEK_SET);
int len = num / 2;
int d = 31;
while (1)
{
if (len - d > 0)
{
// 一次读三十个
read(fd_src, c, d);
write(fd_dest, c, d);
len = len - d;
sleep(1);
}
else
{
// 最后剩下的len个
read(fd_src, c, len);
write(fd_dest, c, len);
sleep(1);
len = 0;
}
if (len == 0)
{
break;
}
}
}
close(fd_src);
close(fd_dest);
return 0;
}