1

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

我有文本文件(它的名字是 prwtest)。其内容被写入 a 到 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 }

在 line number17上,我使用 flag O_APPEND,因此 prwtest 的当前文件偏移量取自 i-node 的当前文件大小。(现在是 26 岁)。

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

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

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

4

3 回答 3

3

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

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

O_APPEND

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

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


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


实际上,虽然我们确实在这样做,但如果您已经这样做 #include <stdio.h>了,为什么不使用标准的文件 I/O ( fopen()/ fseek()/ fwrite()) 而不是 POSIX 特定的东西呢?;-)

于 2016-02-29T09:06:59.427 回答
3

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

因此,在开仓后,仓位仍然存在0,但如果您调用 write,lseekonSEEK_CUR将返回正确的值。

于 2016-02-29T09:07:44.803 回答
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在 Linux 上是错误的:

错误

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

于 2016-02-29T10:50:44.570 回答