为什么lseek会返回0?

时间:2009-02-25 18:33:55

标签: api macos darwin

lseek()应该返回文件描述符的位置。

documentation说:

  

成功完成后,lseek()   返回结果偏移位置   以字节为单位测量        文件的开头。否则,返回值-1   和errno设置为表示   错误。

麻烦的是,这甚至不起作用:

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
printf("size off_t: %i\n", sizeof(off_t));

off_t pos;
pos = lseek(file, (off_t)0, SEEK_CUR);
printf("pos: %lli\n", pos);

// same result for SEEK_SET and SEEK_END
pos = lseek(file, (off_t)2352, SEEK_CUR);
printf("pos: %lli\n", pos);

这给了我:

size off_t: 8
pos: 0
pos: 0

这是为什么?是否有使用原始I / O功能查找当前偏移的替代方法? (readopenlseek,...)

修改1:

我试图让这个例子更简单。

5 个答案:

答案 0 :(得分:6)

尝试添加#include&lt; unistd.h&gt;到顶部。

请参阅:http://forums.macosxhints.com/archive/index.php/t-35508.html

基本上,由于你没有#include <unistd.h>,编译器正在“猜测”lseek()返回一个int。

可能一个int是4字节长,并且因为PPC是“大端”字节顺序,所以你得到的是“顶部”4个字节,它们都是零。

包含unistd.h让编译器意识到lseek()正在返回off_t,所以你不会丢失一半的字节。

答案 1 :(得分:2)

还有其他东西,可能是愚蠢的东西。我尝试了你的代码,如下所示:

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    off_t pos;
    int file ;
    if((file = open("/Users/chasrmartin/.bash_history",O_RDONLY)) == -1){
        perror(argv[0]);
        exit(1);
    }
    printf("size off_t: %i\n", sizeof(off_t));

    pos = lseek(file, (off_t)0, SEEK_CUR);
    printf("pos: %lli\n", pos);

    // same result for SEEK_SET and SEEK_END
    pos = lseek(file, (off_t)2352, SEEK_CUR);
    printf("pos: %lli\n", pos);

    exit(0);
}

得到这个结果:

bash $ gcc foo.c
bash $ ./a.out
size off_t: 8
pos: 0
pos: 2352

(只是明确一点,这是在英特尔的Mac OS / X 10.5.6上。)

更新。

或许这不是愚蠢的。我刚刚在PPC G5上试过它,并得到你的结果。

更新2

好的,这是PPC上的结果:

$ gcc foo.c
$ ./a.out
size off_t: 8
pos: 0
pos: 0

答案 2 :(得分:1)

它是什么类型的文件?这是一个管道吗?因为如果它只是一个普通的文件,它可能不支持寻求:

  

lseek()在无法寻找的设备上的行为是实现定义的。与此类设备关联的文件偏移值未定义。

答案 3 :(得分:0)

您可能希望将测试更改为:

if ( (pos = lseek(file, (off_t)i, SEEK_CUR)) != -1 ) {

你可能在某个地方达到-1,但你在这里测试的是0.

答案 4 :(得分:0)

我不确定我理解你的问题,但这里有一些可能会有所帮助的想法。

  • 偏移0有效;这意味着你在文件的开头
  • 根据您的平台,off_t可能限制为32位无符号。
  • 您打算相对于您目前的职位寻求什么?

- MarkusQ