首先是常用的几个函数 open , read,write,lseek, close
open函数 函数原型 int open(char * path,int oflag,...) 返回值是一个文件描述符 path顾名思义就是文件名 oflage文件是打开方式 第三个形参应用于创建文件时使用 /*创建文件其实还有一个create函数使用 以及openat由于还未使用过这个函数和open的差异 所以不在此处累赘*/ open函数 使用if 判断的时候 注意小细节
read函数 函数原型 ssize_t read(int fd , void* buf , size_t nbytes) 返回值是文件读取字节数 在好几种情况下会出现返回值不等于文件读取字节数 也就是第三个参数nbytes的情况 第二个形参buf读取到buf的内存 文件偏移量(current file offset)受改变
write函数 函数原型 ssize_t write(int fd , const void* buf, size_t nbytes) 返回值是文件写入字节数 fd是文件描述符 将buf内容写入nbytes个字节到文件 但这里需要注意默认情况是需要在系统队列中等待写入(打开方式不同也会不同) //以上三个出错都返回-1
lseek函数off_t lseek(int fd, off_t offset , int whence) 返回值成功函数返回新的文件偏移量 失败-1 fd文件描述符 off_t是有符号的整数 whence其实是和off_t配套使用的 SEEK_SET文件开始处 SEEK_CUR当前值的相对位置 SEEK_END文件长度+-
close函数原型 int close(int fd) 返回值 成功返回0 失败—1 关闭文件描述符
下面就有俩个重要的概念 一个是内核用三种数据结构来表示打开文件 另一个也和它有原因就是文件io的原子性
由于在linux环境下没有画图的软件 就加以简单描述三种文件状态数据结构 第一个是文件描述符fd的描述(我懒没查 我更喜欢知道原理 用的时候再查细节 = =!!)第二个是文件表项 第三个是v节点 第一个第二个是呈链表状
然后文件表项指向v节点 不同的fd文件描述符访问同一文件就是访问不同的fd指向同一个v节点
1 struct Fd{ 2 int fd; //文件描述符 3 void* filePtr; //文件指针指向文件表 4 }; 5 6 7 struct FileTable{ 8 int fileMark; // 文件状态标志 9 off_t offset; //文件偏移量 10 void* vNode; 11 } 12 //其实还有第三个的 我没学到所以也就不害人了
看完上面这个很破很破的代码(命名没有大写)的时候你应该发现一个问题了如果两个线程访问同一文件 会产生一个操作异常其实就是各自的的文件表项的数据异步造成的 可能会造成覆盖另一条进程的数据 这里就体现了原子操作的必要性了 它的意思就是所有操作会一次性完成操作系统不会只执行一半就去执行另一条进程了
fcntl函数 int fcntl(int fd , int cmd,...) 这个函数可以改变已经打开文件的属性 但是要注意必须先获得目前的标志值 然后再设置 上code 应用于一个以创建文件以只读打开 使用fcntl修改打开状态写入文本
1 #include<apue.h> 2 #include<fcntl.h> 3 void set_fl(int fd, int flags) // flags are file status to ture on 4 { 5 int val ; 6 if((val = fcntl(fd,F_GETFL, 0)) < 0){ 7 printf("err -1!"); 8 err_sys("fcntl get error!"); 9 } 10 val |= flags; 11 if( fcntl( fd , F_SETFL , val) < 0){ 12 printf("error 0!"); 13 err_sys("fcontl set error!"); 14 } 15 16 } 17 18 int main(void) 19 { 20 int fd = 0; 21 char buf[] = "xiaochen"; 22 23 if((fd = open("aa.txt" , O_WRONLY )) < 0){ 24 printf("err 1!"); 25 err_sys("open error!"); 26 } 27 set_fl(fd,O_WRONLY); 28 if(write(fd , buf , 8) != 8 ){ 29 printf(" err 2!"); 30 err_sys("write error"); 31 } 32 33 close(fd); 34 return 0; 35 36 }~ ~
由于只是总结不做太多细节描述
完。。。。 //书读少了好多都只知道概念 上面函数都有简单的小demo 我比较懒破代码就不show了 学完一章做个小总结还是很有用的 如果您有一天看见这篇破文章有学习上的问题或者发现博文里我的错误 请联系我很会非常感谢您 qq:1639153000