lseek()
函数说明 | 每一个已打开的文件都有一个读写位置, 当打开文件时通常其读写位置是指向文件开头, 若是以附加的方式打开文件(如O_APPEND), 则读写位置会指向文件尾. 当read()或write()时, 读写位置会随之增加,lseek()便是用来控制该文件的读写位置. |
头文件 | #include <sys/types.h> |
函数原型 | off_t lseek(int fildes, off_t offset, int whence); |
函数参数 | filedes:文件描述符 |
offset:相对于whence的偏移量,以字节为单位。正数向前移动,负数向后移动 | |
whence:当前位置的基准点(3种) | |
1.SEEK_SET:文件的起始位置 | |
2.SEEK_CUR:文件当前读写位置 | |
3.SEEK_END:文件的结束位置 | |
返回值 | 成功:返回目前的读写位置, 也就是距离文件开头多少个字节. |
-1:出错 errno 会存放错误代码. | |
备注 | lseek() 只对常规文件有效 对socket 管道 FIFO等无效 |
lseek() 仅将当前的位移量记录在内核中,并不引起任何I/O操作。 | |
文件位移量可以大于当前的文件长度,在这中情况下, 对该文件的写操作会延长文件,形成空洞。并不占用真实空间。 | |
使用方法 | 1.将读写位置移到文件开头时:lseek(int fildes, 0, SEEK_SET); |
2.将读写位置移到文件尾时:lseek(int fildes, 0, SEEK_END); | |
3.取得目前文件位置时:lseek(int fildes, 0, SEEK_CUR); |
例1:利用lseek() 计算文件大小
#include <stdio.h> #include <stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> int main(int argc,char *argv[]) { int fd, length; if (argc<2) { puts("Please input the open file pathname!\n"); exit(1); } if ((fd=open(argv[1], O_RDONLY))<0) { perror("open error"); exit(1); } /* The offset is set to the size of the file plus 0(offset) bytes. */ if ((length = lseek(fd, 0, SEEK_END))<0 ) { perror("lseek error"); } printf("The file's length is %d\n",length); close(fd); exit(0); }
例2:创建一个空洞文件,思考空洞文件的用途。
#include "apue.h" #include <fcntl.h> char buf1[] = "abcdefghij"; char buf2[] = "ABCDEFGHIJ"; int main(void) { int fd; if ((fd = creat("file.hole", FILE_MODE)) < 0) err_sys("creat error"); if (write(fd, buf1, 10) != 10) err_sys("buf1 write error"); /* offset now = 10 */ if (lseek(fd, 16384, SEEK_SET) == -1) err_sys("lseek error"); /* offset now = 16384 */ if (write(fd, buf2, 10) != 10) err_sys("buf2 write error"); /* offset now = 16394 */ exit(0); }