lseek函数用法

lseek函数用法lseek函数:#include<unistd.h>off_tlseek(intfd,off_toffset,intwhence);返回值:若成功,返回新的文件偏移量;若失败,返回-1可以调用lseek显示地为一个打开文件设置偏移量。每个打开的文件,都有一个与其相关的“当前文件偏移量”(currentfileoffset)…

大家好,欢迎来到IT知识分享网。lseek函数用法"

lseek函数:

#include <unistd.h>

off_t  lseek(int fd, off_t offset, int whence);

                                                                  返回值:若成功,返回新的文件偏移量;若失败,返回-1

可以调用lseek显示地为一个打开文件设置偏移量。

文件偏移都是内核概念,所以lseek并不会引起任何真正的 I/O 操作。

每个打开的文件,都有一个与其相关的“当前文件偏移量”(current file offset)。他通常是一个非负整数(后面将会详细介绍到),用以度量从文件开始处计算的字节数。通常,读、写操作都是从当前文件偏移量处开始,并使偏移量增加所读、写字节数数。按照系统默认的情况,当打开一个文件时,除非指定O_APPEND选项,否则偏移量都被设置为0。

对参数offset的解释与参数whence的值有关:

  • 若whence是SEEK_SET,则文件的偏移量设置为距文件开始处,offset个字节;
  • 若whence是SEEK_CUR,则将文件的偏移量设置为当前值(当前fd所在位置开始算起),增加offset,offset可正,可负;
  • 若whence是SEEK_END,则将文件的偏移量设置为,文件长度加offset,offset可正,可负。

若lseek成功执行,则返回新的文件偏移量,为此可以用下列方式正确打钱文件的当前偏移量:

off_t    currpos;
currpos = lseek(fd, 0, SEEKCUR);

这种方法,也可以用来确定所涉及的文件是否可以设置偏移量。如果文件描述符指向的是一个管道,FIFO或者网络套接字,则lseek返回-1,并将errno设置为ESPIPE。

不是每个文件都能够设置偏移量,有些设备(或者说设备文件)不能使用lseek,linux系统不允许lseek()对tty设备进行操作,此项操作会使得lseek()范围错误代码ESPIPE,也有些文件如管道,FIFO或socket,无法设置偏移量,可以使用如下函数测试是否可以设置偏移量,如果返回-1,则表示不可以。

3个符号量SEEK_SET,SEEK_CUR和SEEK_END是在System V中引入的,在System V之前,whence被指定为0(绝对偏移量),1(相对偏移量),或者2(相对文件尾端的偏移量)。很多软件仍然把这些数字直接写在代码里。

在lseek中的字符1表示长整型,在引入off_t数据类型之前,offset参数和返回值是长整型的。lseek是在UNIX V7中引入的,当时C语言中增加了长整型(在UNIX V6中,用函数seek和tell提供类似功能)。

 实例:下面的程序用于测试对其标准输入能否设置偏移量。

#include "apue.h"
int main(void)
{
    if(lseek(STDIN_FILENO, 0, SEEK_CUR) == -1)
    {
        printf("cannot seek\n");
    }
    else
    {
        printf("seek OK\n");
    }
    exit(0);
}

如果用交互方式调用此程序,则可得:

$ ./a.out < /etc/passwd
seek OK 
$ cat  >  /etc/passwd | ./a.out
cannot seek
$ ./a.out  <  /var/spool/cron/FIFO
cantnot seek

 

通常,文件的当前偏移量应当是一个非负整数,但是,某些设备也可能会允许负的偏移量,但是对于普通文件,其偏移量必须是非负值。因为偏移量可能是负值,所以在比较lseek的返回值时,应当谨慎,不要测试它是否小于0,而是要测试它是否等于-1。

在Intel X86处理骑上运行的FreeBSD的设备,/dev/kmem支持负的偏移量。

因为偏移量(off_t)是带符号数据类型,所以文件的最大长度会减少一半,例如,如果off_t是32位整型,则文件最大长度是2的31次方 – 1字节。

 

linux 中的大部分系统调用来说,如果返回值是负数,那么它一般都是错误的,但是对于lseek来说,这条规则并不适用,lseek的返回值说明:

当lseek执行成功是,他会返回最终以文件其实位置为起点的偏移量。如果出错,则返回 -1 ,同时errno被设置为对应的错误值

也就是说,一般情况下,对于普通文件,lseek的返回值都是非负的整数,但是对于某些设备文件来说,是允许返回负的偏移量。因此想要判断lseek是否真的出错,必须在调用lseek前,将errno重置为0,然后在调用lseek,同时检查返回值是否为 -1 及errno的值。只有当两个同时成立时,才标明lseek真的出错了。

 

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/20940.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信