(6)lseek
lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数:
fd 表示要操作的文件描述符
offset是相对于whence(基准)的偏移量
whence 可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾
返回值:文件读写指针距文件开头的字节大小,出错,返回-1
lseek 主要作用是移动文件读写指针,因此还有以下两个作用
1.拓展文件,不过一定要一次写的操作。迅雷等下载工具在下载文件时候先扩展一个空间,然后再下载的。
#include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<errno.h> #include<stdlib.h> int main() { int fd=open("abc",O_RDWR); if(fd<0) { perror("open abc"); exit(-1); } //扩展一个文件,一定要有一次写操作 lseek(fd,ox1000,SEEK_SET); write(fd,“a”,1); close(fd); return 0; }
注:看一个文件里边的内容 od -tcx 文件名
2.获取文件大小
利用返回值:文件读写指针距文件开头的字节大小,出错,返回-1
fd=open("hello",O_RDWR); if(fd<0) { perror("open hello"); exit(-1); } printf("hello size=%d ",lseek(fd,0,SEEK_END));
close(fd);
3.移动读写指针的位置
(7)fcntl
获取或设置文件的访问控制属性
功能描述:根据文件描述词来操作文件的特性。
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fcntl()针对(文件)描述符提供控制。参数fd是被参数cmd操作(如下面的描述)的描述符。针对cmd的值,fcntl能够接受第三个参数int arg。
[返回值]
fcntl()的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:F_DUPFD , F_GETFD , F_GETFL以及F_GETOWN。
F_DUPFD 返回新的文件描述符
F_GETFD 返回相应标志
F_GETFL , F_GETOWN 返回一个正的进程ID或负的进程组ID
F_SETFD
fcntl函数有5种功能:
1. 复制一个现有的描述符(cmd=F_DUPFD).
2. 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
3. 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
4. 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
5. 获得/设置记录锁(cmd=F_GETLK , F_SETLK或F_SETLKW).
#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h> #define MSG_TRY "try again " int main(void) { char buf[10]; int n; int flags; flags = fcntl(STDIN_FILENO, F_GETFL);//获取一个文件的访问控制属性 flags |= O_NONBLOCK; if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1)//设置 { perror("fcntl"); exit(1); } tryagain: n = read(STDIN_FILENO, buf, 10); if (n < 0) { if (errno == EAGAIN) { sleep(1); write(STDOUT_FILENO, MSG_TRY,strlen(MSG_TRY)); goto tryagain; } perror("read stdin"); exit(1); } write(STDOUT_FILENO, buf, n); return 0; }
fcntl
(8)ioctl
ioctl用于向设备发控制和配置命令大部分驱动,除了需要具备读写设备的能力之外,还需要具备对硬件控制的能力。
#include<sys/ioctl.h> int ioctl(int d,int request,...);
其中d就是用户程序打开设备时使用open函数返回的文件描述符,request就是用户程序对设备的控制命令,至于后面的省略号,则是一些补充参数,一般最多一个,有或没有是和request的意义相关的,详情请参考man 2 ioctl_list以了解更多。ioctl函数是文件结构中的一个属性分量,就是说如果驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道或其它一些自己想要控制且设备支持的功能。
fcntl 共性,ioctl个性
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/ioctl.h> int main(void) { struct winsize size;//winsize指定终端文件的大小 if(isatty(STDOUT_FILENO==0)//判断是否为终端文件,大于0是,==0不是 exit(1); if(ioctl(STDOUT_FILENO,TIOCGWINSZ,&size)<0)//获取终端窗口大小存入到size { perror("ioctl TIOCGWINSZ error"); exit(1); } printf(%d rows,%d columns ",size.ws_row,size.ws_col); return 0; }
在图形界面的终端里多次改变终端窗口大小并运行该程序,观察结果。