Linux:文件操作的系统调用

int open(const char pathname, int flags);*

//用于打开一个已存在的文件

int open(const char pathname, int flags,mode_t mode);*

//用于新建一个文件,并设置访问权限

  • pathname:将要打开的文件路径和名称

  • flags : 打开标志,如 O_WRONLY 只写打开

  • O_RDONLY 只读打开

  • O_RDWR 读写方式打开

  • O_CREAT 文件不存在则创建

  • O_APPEND 文件末尾追加

  • O_TRUNC 清空文件,重新写入

  • mode: 权限 如: “0600”

  • 返回值: 为文件描述符

ssize_t read(int fd, void buf, size_t count);*
  • fd 对应打开的文件描述符

  • buf 存放数据的空间

  • count 计划一次从文件中读多少字节数据

  • 返回值: 为实际读到的字节数

ssize_t write(int fd, const void buf,size_t count);*
  • fd 对应打开的文件描述符

  • buf 存放待写入的数据

  • count 计划一次向文件中写多少数据

int close(int fd);
  • fd 要关闭的文件描述符

pid_t getpid(void); 返回子进程的PID

pid_t getppid(void); 返回父进程的PID

程序完成对一个普通文件的复制,(类似 cp 命令)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
/*
*将当前目录下名为"passwd"的普通文件复制一份,新文件名叫"newpasswd"
*/
int main()
{
char buff[256] = {0};//存放拷贝来的数据的空间
int fdr = open("passwd",O_RDONLY);
assert( fdr != -1 );

int fdw = open("newpasswd",O_WRONLY|O_CREAT,0600);
assert( fdw != -1 );

int n = 0;
while( (n = read(fdr,buff,256)) > 0 )
{
	write(fdw,buff,n);
}
close(fdr);
close(fdw);
}

PCB:进程控制块 ==进程描述符 ==struct task_struct

文件打开后要不再使用后要及时关闭,否则文件描述符会一直增长,会导致最终无法打开文件

先打开一个文件再复制进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
//分析程序执行的打印结果
int main()
{
char buff[128] = {0};
//myfile.txt 自己创建,并写入内容为“abcdef”
int fd = open("myfile.txt",O_RDONLY);
pid_t pid = fork();
assert( pid != -1 );
if ( pid == 0 )
{
read(fd,buff,1);
printf("child buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("child buff=%s\n",buff);
}
else
{
read(fd,buff,1);
printf("parent buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("parent buff=%s\n",buff);
}
close(fd);
}

由于 fork 创建的子进程的 PCB 是拷贝父进程的,子进程的 PCB 中的文件表指向打开文件的指针只是拷贝了父进程 PCB 中的值,所以父子进程会共享父进程 fork 之前打开的所有文件描述符,也就是共享文件偏移量,所以打印结果为abcd
请添加图片描述
将代码更换为先复制进程再打开文件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
//分析程序执行的打印结果
int main()
{
pid_t pid = fork();
assert( pid != -1 );

char buff[128] = {0};
//myfile.txt 自己创建,并写入内容为“abcdef”
int fd = open("myfile.txt",O_RDONLY);
if ( pid == 0 )
{
read(fd,buff,1);
printf("child buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("child buff=%s\n",buff);
}
else
{
read(fd,buff,1);
printf("parent buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("parent buff=%s\n",buff);
}
close(fd);
}

如果提前将fork进程复制,就会产生独立于父进程的新文件表,父进程与子进程的偏移量也各自独立,所以打印内容也相互独立,所以打印为aabb
在这里插入图片描述

系统调用与库函数的区别

区别: 系统调用的实现在内核中,属于内核空间,库函数的实现在函数库中,属于用户空间。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小新 蜡笔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值