在《Unix\Linux编程实践教程》 一书第56页有一段话:
Unix每次打开一个文件都会保存一个指针来记录文件的当前位置,如图示
read从当前位置读入指定长度的数据,
然后移动当前位置指针,
指向下一个未读的数据
当从文件读数据时,内核从指针所标明的地方开始,
读取指定的字节,然后移动位置指针,
指向下一个未被读取的字节,写文件的操作也是类似的。
指针是与文件描述符相关联的,而不是与文件关联,
所以如果两个程序同时打开一个文件,这时会有两个指针,
两个程序对文件的读操作不会互相干扰。
要接开文件当前指针的面纱,定位它,有个方法:
使用off_t oldpos = lseek(int fd,off_t dist, int base)函数可以返回当前位置——lseek(fd, 0, SEEK_CUR),SEEK_CUR这个参数标明,在当前指针的位置做零位移,所以返回的同样是当前指针位置。
借书中的例子结合这个函数,查看文件打开时当前指针的移动动向:
#include <stdio.h>
#include <utmp.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
struct utmp current_record;
int utmpfd,currfd;//文件描述符,当前指针
int reclen =sizeof(current_record);
if((utmpfd=open(UTMP_FILE, O_RDONLY)) ==-1){
perror(UTMP_FILE);
exit(1);
}
currfd = lseek(utmpfd,0, SEEK_CUR);
printf(">utmpfd=%d,currfd=%d,sizeof(utmp)=%d\n",utmpfd,currfd,sizeof(struct utmp));
while(read(utmpfd, ¤t_record, reclen) == reclen)
{
currfd = lseek(utmpfd,0, SEEK_CUR);
printf(">utmpfd=%d,currfd=%d\n",utmpfd,currfd);
show_info(¤t_record);
}
close(utmpfd);
return0;
}
show_info( struct utmp *utbufp )
{
printf("%-8.8s", utbufp->ut_name); /* the logname */
printf(""); /* a space */
printf("%-8.8s", utbufp->ut_line); /* the tty */
printf(""); /* a space */
printf("%10ld", utbufp->ut_time); /* login time */
printf(""); /* a space */
#ifdef SHOWHOST
printf("(%s)", utbufp->ut_host); /* the host */
#endif
printf("\n"); /* newline */
}
这段代码,原是读取utmp文件,该文件记录了用户登录详细信息,逐条读取utmp结构体大小的数据(utmp结构体成员包含登录信息),理论上来讲,每次read大小为utmp结构体的数据后后,当前指针都应该后移utmp结构体大小,那么查看一下结果是不是呢?
>utmpfd=3,currfd=0,sizeof(utmp)=384 >utmpfd=3,currfd=384 reboot ~ 1315959413 >utmpfd=3,currfd=768 runlevel ~ 1315959413 >utmpfd=3,currfd=1152 LOGIN tty4 1315959413 >utmpfd=3,currfd=1536 LOGIN tty5 1315959413 >utmpfd=3,currfd=1920 LOGIN tty2 1315959414 >utmpfd=3,currfd=2304 LOGIN tty3 1315959414 >utmpfd=3,currfd=2688 lizh tty6 1315979221 >utmpfd=3,currfd=3072 lizh tty1 1315959443 >utmpfd=3,currfd=3456 lizh pts/2 1315979126 >utmpfd=3,currfd=3840 lizh pts/3 1315979551 >utmpfd=3,currfd=4224 lizh pts/4 1316051702
没错,每次read数据,当前指针currfd间隔正好是sizeof(struct utmp)。