1、一个进程中两次打开同一个文件,分别读取,看看会发生什么
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
int fd1 = -1,fd2 = -1;//文件描述符
char buf1[100] = {0};
char buf2[100] = {0};
char writebuf[20] = "i love linux LT.";
int ret1 = 0,ret2 =0;
/*打开一个文件*/
fd1 = open("a.txt",O_RDWR);
fd2 = open("a.txt",O_RDWR);
if((-1 == fd1)||(-1 == fd2))
{
printf("文件打开错误.\n");
}
else
{
printf("文件打开成功. fd1 = %d.\n",fd1);
printf("文件打开成功. fd2 = %d.\n",fd2);
}
/*写文件*/
#if 0
ret = write(fd, writebuf, strlen(writebuf));
if(ret < 0)
{
printf("写入失败.\n");
}
else
{
printf("写入的字节数为:%d.\n",ret);
}
#endif
//ret = lseek(fd, 0, SEEK_SET);
/*读取文件的内容*/
#if 1
memset(buf1, 0 ,sizeof(buf1));
memset(buf2, 0 ,sizeof(buf2));
ret1 = read(fd1, buf1, 20);
ret2 = read(fd2, buf2, 20);
if((-1 == ret1)||(-1 == ret2))
{
printf("读取失败.\n");
}
else
{
printf("f1 :%d.\n", fd1);
printf("f1读出的字节数为:%d.\n",ret1);
printf("文件内容为:[%s].\n",buf1);
printf("f2 : %d.\n", fd2);
printf("f2读出的字节数为:%d.\n",ret2);
printf("文件内容为:[%s].\n",buf2);
}
#endif
/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了
close(fd1);
close(fd2);
return 0;
}
我们发现读的时候有各自的指针,不会存在两个进程相互影响
关于写入
有的时候需要分别写,有的时候需要接续写,关键看用户的需求,默认情况下是分别写,如果想要接续写入,就在打开时加入O_APPEND 即可
O_APPEND 的内部原理,就是文件指针的移动嘛,分别写两个fd有各自的文件指针,接续写公用一个文件指针。确切的说是移动自己的文件指针的同时,也去移动其他的文件指针,也就是说两个文件指针关联起来了,一个动了,另一个也会跟着动。
O_APPEND 对文件指针的影响,对文件读写是原子的
原子操作,整个操作开始是不会被打断的,必须等结束后才能得以调度。原子就是模块化的进行完才能被打断,交出CPU的使用权。
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
int fd1 = -1,fd2 = -1;//文件描述符
char buf1[100] = {0};
char buf2[100] = {0};
char writebuf[20] = "i love linux LT.";
int ret1 = 0,ret2 =0;
/*打开一个文件*/
fd1 = open("a.txt",O_RDWR | O_TRUNC | O_CREAT | O_APPEND, 0666);//读写/从头写/没有就创建/接续写入
fd2 = open("a.txt",O_RDWR | O_TRUNC | O_CREAT | O_APPEND, 0666);//读写/从头写/没有就创建/接续写入
if((-1 == fd1)||(-1 == fd2))
{
printf("文件打开错误.\n");
}
else
{
printf("文件打开成功. fd1 = %d.\n",fd1);
printf("文件打开成功. fd2 = %d.\n",fd2);
}
/*写文件*/
#if 1
while(1)
{
ret1 = write(fd1, "ab", 2);
ret2 = write(fd2, "cd", 2);
sleep(1); //延时1s
if(ret1 < 0)
{
printf("写入失败.\n");
}
else
{
printf("写入的字节数为:%d.\n",ret1);
}
}
#endif
//ret = lseek(fd, 0, SEEK_SET);
/*读取文件的内容*/
#if 0
memset(buf1, 0 ,sizeof(buf1));
memset(buf2, 0 ,sizeof(buf2));
sleep(1); //延时1s
ret1 = read(fd1, buf1, 20);
ret2 = read(fd2, buf2, 20);
if((-1 == ret1)||(-1 == ret2))
{
printf("读取失败.\n");
}
else
{
printf("f1 :%d.\n", fd1);
printf("f1读出的字节数为:%d.\n",ret1);
printf("文件内容为:[%s].\n",buf1);
printf("f2 : %d.\n", fd2);
printf("f2读出的字节数为:%d.\n",ret2);
printf("文件内容为:[%s].\n",buf2);
}
#endif
/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了
close(fd1);
close(fd2);
return 0;
}