lseek()

时间:2016-02-29 09:03:00

标签: c linux file lseek

我对lseek()的返回值(新文件偏移量)感到困惑

我有文本文件(它的名字是prwtest)。其内容写入a to z。

而且,我写的代码是关注的,

  1 #include <unistd.h>
  2 #include <fcntl.h>
  3 #include <stdlib.h>
  4 #include <stdio.h>
  5 #include <string.h>
  6 
  7 #define BUF 50
  8 
  9 int main(void)
 10 {
 11         char buf1[]="abcdefghijklmnopqrstuvwxyz";
 12         char buf2[BUF];
 13         int fd;
 14         int read_cnt;
 15         off_t cur_offset;
 16 
 17         fd=openat(AT_FDCWD, "prwtest", O_CREAT | O_RDWR | O_APPEND);
 18         cur_offset=lseek(fd, 0, SEEK_CUR);
 19         //pwrite(fd, buf1, strlen(buf1), 0);
 20         //write(fd, buf1, strlen(buf1));
 21         //cur_offset=lseek(fd, 0, SEEK_END);
 22 
 23         printf("current offset of file prwtest: %d \n", cur_offset);
 24 
 25         exit(0);
 26 }

在行号17上,我使用标志O_APPEND,因此prwtest的当前文件偏移量取自i-node的当前文件大小。 (这是26)。

在行号18上,我使用了SEEK_CUR使用的lseek(),偏移量为0。

但结果值cur_offset为0.(我假设它必须是26,因为SEEK_CUR表示当前文件偏移量。) 但是,SEEK_END给了我的想法,cur_offset是26。

为什么lseek(fd, 0, SEEK_CUR);给我的返回值为0,而不是26?

3 个答案:

答案 0 :(得分:3)

您的问题是open() / openat(),而不是lseek()

open()联机帮助页,强调我的:

  

<强> O_APPEND

     

文件以追加模式打开。 在每次写入(2)之前,文件偏移量位于文件的末尾,就像使用lseek(2)一样。

由于您没有写入文件,因此永远不会将偏移重新定位到文件的末尾。

在我们这样做的时候,你应该在结束程序之前关闭文件......

实际上,虽然我们非常,但如果你已经 #include <stdio.h>,为什么不使用标准的文件I / O({{1 }} / fopen() / fseek())而不是POSIX特定的东西? ; - )

答案 1 :(得分:3)

O_APPEND在每次写入文件之前生效,而不是在打开文件时生效。

因此,在打开后,该位置仍为0但如果您调用了写入,则lseek上的SEEK_CUR将返回正确的值。

答案 2 :(得分:1)

此外,在Linux上,您的注释掉的代码将无法正常工作。这段代码:

 17         fd=openat(AT_FDCWD, "prwtest", O_CREAT | O_RDWR | O_APPEND);
 18         cur_offset=lseek(fd, 0, SEEK_CUR);
 19         pwrite(fd, buf1, strlen(buf1), 0);

将无法在文件开头写入buf1的内容(除非文件为空)。

pwrite on Linux是错误的:

  

BUGS

     

POSIX要求打开带有O_APPEND标志的文件   对pwrite()写入数据的位置没有影响。   但是,在Linux上,如果使用O_APPEND打开文件,pwrite()   将数据附加到文件的末尾,而不管其值是多少   偏移