Linux中的lseek 函数与fcntl函数
lseek 函数
所有打开的文件都有一个当前文件偏移量(current file offset),也叫读写偏移量和指针。文件偏移量通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数(下一个read()或write()操作的文件起始位置)。文件的第一个字节的偏移量为0。
文件打开时,会将文件偏移量设置为指向文件开始(使用O_APPEND除外),以后每次read()和write()会自动对其调整,以指向已读或已写数据的下一字节。因此连续的read()和write()将按顺序递进,对文件进行操作。使用Iseek函数可以改变文件的偏移量。
函数描述:
移动文件指针
头文件:
1.#include
2.#include
函数原型:
off_t lseek(int fd, off_t offset, int whence);
函数参数:
1.fd:文件描述符
2.offset:字节数,以whence参数为基点解释offset
3.whence:解释offset 参数的基点
1)SEEK_SET:文件偏移量设置为offset
2)SEEK_CUR:文件偏移量设置为当前文件偏移量加上offset,offset可以为负数
3)SEEK_END:文件偏移量设置为文件长度加上offset ,offset可以为负数
函数返回值:
若Iseek成功执行,则返回新的偏移量。
失败返回-1并设置errno
lseek 函数常用操作:
1.文件指针移动到头部
Iseek(fd, 0, SEEK_SET);
2.获取文件指针当前位置
int len = Iseek(fd, 0, SEEK_CUR);
3.获取文件长度
int len = Iseek(fd, 0, SEEK_END);
4.Iseek实现文件拓展
1)Iseek(fd, n,SEEK_END);//扩展n个字节
2)write();//扩展后需要执行一次写操作才能扩展成功
int fd=open("./a.txt",O_RDWR);
char buf[1024];
int ret=read(fd,buf,sizeof(buf));
int offset=lseek(fd,0,SEEK_CUR);//获取当前文件偏移量
printf("offset=%d\n",offset);
int len=lseek(fd,0,SEEK_END);//获取文件长度
printf("len=%d\n",len);
lseek(fd,0,SEEK_SET);//文件指针指向头部
lseek(fd,1000,SEEK_END);//从文件尾部开始向后扩展1000字节
write(fd," ",1);//为了扩展成功,所编写一个数据
len=lseek(fd,0,SEEK_END);
printf("lenght=%d\n",len);
close(a.txt);
fcntl函数
函数描述:
对打开的文件描述符进行控制,如获取或修改打开文件的状态标志(对应open函数的flags参数)
函数原型:
int fcntl(int fd, int cmd, .../* arg */);
函数参数:
1.fd:要控制的文件描述符
2.cmd:不同值对应不同的操作
1) cmd为F_GETFL:获取文件描述符的flag值
2)cmd为F_SETFL:设置(修改)文件描述符的flag值
3)cmd为F_DUPFD:复制文件描述符,与dup()函数功能相同
函数返回值:返回值取决于 cmd
1.成功
1).若cmd为F_DUPFD,返回一个新的文件描述符
2.)若cmd为F_GETFL,返回文件描述符的flags值
3).若cmd为F_SETFL,返回0
2.失败返回-1,并设置errno值
fcntl函数常用的操作:
1.获取文件的属性标志
int flags=fcntl(fd,F_GETFL):
int fd=open("./a.txt",O_RDONLY|O_NONBLOCK);
printf("fd=%d\n",fd);
int flags=fcntl(fd,F_GETFL);
if(flags&O_NONBLOCK){
printf("flags include O_NONBLOCK\n");
}
//O_RDONLY 为0,flags 需要和O_ACCMODE按位与后判断:
if((flags&O_ACCMODE)==O_RDONLY){
printf("flags include O_RDONLY\n");
}
2.修改文件状态标志(只允许修改某些标志 如:O_APPEND,O_NONBCLOK)
1)flags=flags | O_NONBCLOCK
2)fcntl(fd,F_SETFL,flag)
#include<errno.h>
int flags=fcntl(0,F_GETFL);
flags|=O_NONBCLOCK;
fcntl(0,F_SETFL,flags);
char buf[1024];
int read_count=read(0,buf,sizeof(buf));
if(read_count==-1&& errno==ENGAIN){
printf("errno is EAGAIN\n");
}
printf("read_count=%d\n",read_count);
write(1,buf,read_count);
3.复制文件描述符,使用大于等于startfd 的最小未用值作为新的文件描述符
int newfd=fcntl(fd,F_DUPFD,startfd);