lseek,fcntl,ioctl函数
函数说明:
每一个已打开的文件都有一个读写位置, 当打开文件时通常其读写位置是指向文件开头, 若是以附加的方式打开文件(如O_APPEND), 则读写位置会指向文件尾. 当read()或write()时, 读写位置会随之增加,lseek()便是用来控制该文件的读写位置. 参数fildes 为已打开的文件描述词, 参数offset 为根据参数whence来移动读写位置的位移数.
注意其每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。但是有一个例外,如果以O_APPEND方式打开,每次写操作都会在文件末尾追加数据,然后将读写位置移到新的文件末尾。lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)。
lseek扩展文件:
touch创建文件test,注意其大小为0:
#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> int main(void) { int fd=open("test",O_RDWR);//假设已经存在test文件并且有读写权限 if(fd<0) { perror("open test"); exit(-1); } //扩展一个文件,一定要有写操作 0x1000为4096 lseek(fd,0x1000,SEEK_SET); write(fd,"a",1); close(fd); return 0; }
运行结果:
可以看到文件大小变成了4097,为4096加上我们写入的一个字符a。注意,如果程序中没有write函数进行写操作,test文件大小不会改变。
lseek获取文件大小:
#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> int main(void) { int fd=open("hello",O_RDWR); if(fd<0) { perror("open hello"); exit(-1); } long long int len; //第二个参数到SEEK_END的长度,off_t在64为系统中,通常为long long int,32的为long len= lseek(fd,0,SEEK_END); printf("%lld\n",len); close(fd); return 0; }
创建hello文件,写入hello文本,一共6个字符,包含最后一个\n.
输出:
通过od指令也可以看出大小为6.
fcntl
先前我们以read终端设备为例介绍了非阻塞I/O,为什么我们不直接对STDIN_FILENO做
非阻塞read,而要重新open一遍/dev/tty呢?因为STDIN_FILENO在程序启动时已经被自动
打开了,而我们需要在调用open时指定O_NONBLOCK标志。这里介绍另外一种办法,可以用
fcntl函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这
些标志称为File Status Flag),而不必重新open文件。
#include <unistd.h> #include <errno.h> #include <stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<sys/ioctl.h> int main(void) { struct winsize size; if (isatty(STDOUT_FILENO) == 0) { exit(1); } if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)<0) { perror("ioctl TIOCGWINSZ error"); exit(1); } printf("%d rows, %d columns\n", size.ws_row, size.ws_col); return 0; }
在图形界面的终端里多次改变终端窗口的大小并运行该程序,观察结果。
没有人是所有内核驱动或者应用函数都记得的,所以很多时候,我们需要借助谷歌必应百度搜索,一点一点积累。
欢迎加入作者的小圈子
扫描下方左边二维码加入QQ交流群,扫描下方右边二维码关注个人微信公众号并获取更多隐藏干货,QQ交流群:816747642 微信公众号:Crystal软件学堂
作者:Crystal软件学堂 bilibili视频教程地址:https://space.bilibili.com/5782182 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在转载文章页面给出原文连接。 如果你觉得文章对你有所帮助,烦请点个推荐,你的支持是我更文的动力。 文中若有错误,请您务必指出,感谢给予我建议并让我提高的你。 |