使用 lseek() 系统调用重置文件位置

reset the file location using lseek() system call

我尝试使用系统调用 lseek() 返回文件开头或到达文件结尾。

我使用的确切代码是:

int location = lseek(fd, 0, SEEK_SET) //get back to the beginning
int location = lseek(fd, 0, SEEK_END) //reach to the end

但是,在重置文件位置后,每当我尝试使用 read() 时,read() 的 return 值总是设置为 -1,这意味着出现了错误。此外,我收到的 errno 消息是 Bad file descriptor。有谁知道我该怎么办?

PS:我尝试关闭并重新打开文件以帮助我返回到文件的开头并且它起作用了。但是我不知道如何在不使用 lseek() 的情况下到达文件末尾并以相反的顺序读取整个文件。

另外:一个可重现的例子是:

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

int main(void)
{
    int fd;
    char buffer[1000];

    fd = creat("newFile", 0777);

    memset(buffer, 'a', 500);
    write(fd, buffer, 500); // fill up

    int location = lseek(fd, 0, SEEK_SET); //get back to the beginning

    int read_bytes = read(fd, buffer, 500);
    // this should return the bytes it reads but it actually returns -1
    printf("%d\n", read_bytes);
    return 0;
}

creat 函数不允许您从文件中读取。它只允许您写入。

来自 creat(2):

creat()
A call to creat() is equivalent to calling open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC.

这里的重要部分是O_WRONLY。这意味着 "write only".

如果你想打开文件(并创建它)进行读写,那么你可以像这样使用open

int fd = open("newFile", O_CREAT|O_RDWR|O_TRUNC, 0777);

这里的重要部分是 O_RDWR。这意味着 "read and write".
如果你想让 open 在文件已经存在的情况下给出错误,请添加 O_EXCL 标志;这会导致 -1 被返回并且 errno 被设置为 EEXIST 如果当您尝试创建它时文件已经存在。

建议代码如下:

  1. 干净地编译
  2. 正确声明变量类型
  3. 正确创建文件
  4. 正确包含所需的头文件
  5. 正确检查 C 库函数的错误指示(并正确处理任何错误)

现在,建议的代码:

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

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <string.h>
#include <unistd.h>

int main(void)
{
    int fd;
    char buffer[1000];

    // fd = creat("newFile", 0777);
    fd = open("newFile", O_CREAT|O_RDWR|O_TRUNC, 0777);
    if( fd < 0 )
    {
        perror( "open failed" );
        exit( EXIT_FAILURE );
    }

    memset(buffer, 'a', 500);
    write(fd, buffer, 500); // fill up

    off_t location = lseek(fd, 0, SEEK_SET); //get back to the beginning

    printf( "%ld\n", location );

    ssize_t read_bytes = read(fd, buffer, 500);

    if( read_bytes < 0 )
    {
        perror( "read failed" );
        exit( EXIT_FAILURE );
    }


    // this should return the bytes it reads but it actually returns -1
    printf("%ld\n", read_bytes);

    return 0;
}

A​​ 运行 的程序结果为:

0
500

建议 reading/understanding 您的代码使用的任何 C 库函数的手册页