文件I/O操作函数 lseek()
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); }
作家格拉德威尔在《异数》一书中指出:“人们眼中的天才之所以卓越非凡,并非天资超人一等,而是付出了持续不断的努力。只要经过1万小时的锤炼,任何人都能从平凡变成超凡。”他将此称为“一万小时定律”。要成为某个领域的专家,需要10000小时,按比例计算就是:如果每天工作四个小时,一周工作五天,那么成为一个领域的专家至少需要十年。