一.文件操作
1.文件的写入与创建
代码:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{
int fd = open("file.txt",O_WROMLY|O_CREAT,0600);
if(fd=-1)
{
printf("open err\n");
exit(0);
}
write(fd,"hello",5);
close(fd);
}
文件的写入:0_WRONLY;创建:O-CREAT
当文件存在时,直接写入,当文件不存在时,先通过O-CREAT创建文件,再写入。
2.文件的只读
代码:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{
int fd = open("file.txt",O_RDONLY);
if(fd=-1)
{
printf("open err\n");
exit(0);
}
char buff[128];
int n=read(fd,buff,127);
printf("n=%d,buff=%s\n",n,buff);
close(fd);
}
文件的只读:O_RDONLY,在已存在的文件中读取内容;
fd:系统调用内核函数的调用号
buff:接受读取的内容,n:读取到的字节数
二.相关问题分析
1.先打开文件,在复制进程
代码:
#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 之前打开的所有
文件描述符。如下图所示:
2.先复制进程,再打开文件
代码:
#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 );
if ( pid == 0 )
{
read(fd,buff,1);
printf("child buff=%s\n",buff);
sleep(1);
char buff[128] = {0};
//myfile.txt 自己创建,并写入内容为“abcdef”
int fd = open("myfile.txt",O_RDONLY);
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);
}
先复制再打开文件:父进程和子进程各自打开文件,享用自己的文件偏移量
三.文件的复制
代码:
#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);
}
运行:./mycp filename newfilename
四.系统调用和库文件的区别
区别: 系统调用的实现在内核中,属于内核空间,库函数的实现在函数库中,属于用
户空间。
系统调用执行过程如下图: