每个打开文件都有一个与其相关联的"当前文件位移量"。它是一个非负整数,用以度量从文件开始处计算的字节数。系统默认当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。即始终指向下一个要读或写的位置。
lseek仅将当前的文件位移量记录在内核内,它并不引起任何I/O操作。然后,该位移量用于下一个读或写操作。
文件位移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将延长该文件,并在文件中构成一个空洞,这一点是允许的。位于文件中但没有写过的字节都读写为0.
下面创建一个含有空洞的文件:
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
int id = open("file.hole",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
if(id < 0)
{
perror("open error");
return 0;
}
int n = write(id,"abcdefghij",10);
if(n != 10)
{
perror("write error");
return 0;
}
if(lseek(id,40,SEEK_SET) == -1)
{
perror("lseek error");
return 0;
}
n = write(id,"abcdefghij",10);
if(n != 10)
{
perror("write error");
return 0;
}
close(id);
return 0;
}
hexdump -c file.hole
0000000 a b c d e f g h i j \0 \0 \0 \0 \0 \0
0000010 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 a b c d e f g h
0000030 i j
然后再打开空洞文件,先lseek定位到40,再读再写。
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
int id = open("file.hole",O_RDWR);
if(id < 0)
{
perror("open error");
return 0;
}
if(lseek(id,40,SEEK_SET) == -1)
{
perror("lseek error");
return 0;
}
char buf[100]={0};
int n = read(id,buf,5);
printf("%s\n",buf);
n = write(id,"pstxyz",3);
if(n != 3)
{
perror("write error");
return 0;
}
close(id);
return 0;
}
./lseek2.exe
abcde
<mct>hexdump -c file.hole
0000000 a b c d e f g h i j \0 \0 \0 \0 \0 \0
0000010 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 a b c d e p s t
0000030 i j
0000032
可以看出,在写的时候是覆盖,而不是插入。
本文永久更新地址://m.ajphoenix.com/linux/22125.html