一般来说,IO是线性的。但某些应用要跳跃式读取文件,需要随机访问而不是线性访问时,lseek()便排上了用场。lseek()系统调用能够将文件描述符的位置指针设置成指定值。lseek()只更新文件位置,没有执行其它操作,也并不初始化任何IO。
lseek()长啥样?
这里是lseek()函数原型及其参数返回值:
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
lseek的应用场景:
设定文件中指针的位置
lseek()调用最常见的用法就是将指针定位到文件的开始、末尾或确定文件描述符的当前文件位置。
举个例子:
- 该代码将文件位置指针设置为1024
off_t ret=lseek(fd, (off_t)1024, SEEK_SET);
- 把fd的文件位置设置成文件末尾
off_t ret=lseek(fd, 0, SEEK_END);
- 确定当前文件位置
int pos=lseek(fd, 0, SEEK_CUR);
利用lseek()获取文件大小
int main()
{
int fd=open("test.txt",O_RDWR);
if(fd<0){
perror("open test.txt error!");
exit(1);
}
int length=lseek(fd,0,SEEK_END);
printf("file size:%d\n", length);
close(fd);
return 0;
}
使用lseek()扩展文件大小
lseek(fd, 100, SEEK_END);
write(fd, "a", 1);
这两行代码表示会定位到fd指向文件末尾之后的100字节,并写入一个“a”。
而在文件的新长度和旧长度之间的空间会用0来填充。这种零填充区间称为“空洞(hole)”。在UNIX系文件系统上,空洞不占用任何物理磁盘空间。这意味着文件系统上所有文件的大小加起来可以超过磁盘的物理大小。包含空洞的文件称为“稀疏文件(sparse file)”。稀疏文件可以节省很多空间,并提升性能,因为操作空洞不会产生任何物理IO。
对文件空洞部分的读请求会返回相应的二进制0。
一般来说,使用truncate()函数直接拓展文件。