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; }