红联Linux门户
Linux帮助

linux上lseek的理解

发布时间:2016-07-06 15:09:11来源:linux网站作者:mct123
每个打开文件都有一个与其相关联的"当前文件位移量"。它是一个非负整数,用以度量从文件开始处计算的字节数。系统默认当打开一个文件时,除非指定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