gpt4 book ai didi

c - 有没有一种快速可靠的 POSIX 方法来检查当前文件偏移量是否在文件末尾?

转载 作者:IT王子 更新时间:2023-10-29 00:43:19 25 4
gpt4 key购买 nike

如何使用低级 POSIX 函数检查当前写入位置是否在文件末尾?第一个想法是使用 lseek 和 fstat:

off_t sk;
struct stat st;
sk = lseek (f, 0, SEEK_CUR);
fstat (f, &st);
return st->st_size == sk;

但是 st->st_size 反射(reflect)的是实际大小而不是磁盘文件大小,即不包括内核缓冲数据?

另一个想法是使用

off_t scur, send;
scur = lseek (f, 0, SEEK_CUR);
send = lseek (f, 0, SEEK_END);
lseek (f, scur, SEEK_START);
return scur == send;

但这似乎不是一种快速且适当的方法。

而且这两种方式似乎都是非原子的,因此如果有另一个进程附加到文件,则可以在检查当前偏移量后更改大小。

最佳答案

However does st->st_size reflect the actual size but not the disk file size, i.e. not including kernel buffered data?

我不明白你所说的内核缓冲数据st->st_size 中的数字反射(reflect)了文件的字符大小。因此,如果文件有 1000000 个字符,则 st->st_size 的数字将为 1000000,字符位置从 0999999

在 POSIX 系统中有两种获取文件大小的方法:

  • 执行 off_t saved = lseek(fd, 0, SEEK_END);,返回实际位置(您必须保存它,以便稍后恢复),然后第二次调用 off_t file_size = lseek(fd, saved, SEEK_SET); 返回你之前的位置,但以数字形式返回你之前的位置(这是文件的最后位置,在最后一个字符之后)如果你检查这个,这将与 st->st_size 返回的值匹配。
  • 对文件描述符执行 stat(2) 以获得您提到的值。

如果您有多个线程或进程与您共享文件描述符(通过 dup(2) 系统调用,或 fork()ed process) 如果他们在你的两个之间进行了 read(2)write(2)lseek(2) 调用lseek 调用,您将丢失您之前在文件中的位置,并且将无法恢复到正确的位置。这很奇怪,并且不推荐第一种方法。

最后,在内核中完成的文件缓冲与文件大小没有关系。您始终可以在 stat(2) 上获得真实的文件大小。唯一让您感到困惑的是当您运行以下代码片段时在内核中所做的节省(但这对您来说是透明的,您不必考虑它,除非您要将文件复制到另一个地方)。只需运行这个小程序:

#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd = open("file", O_WRONLY | O_CREAT | O_TRUNC, 0666);
lseek(fd, 1000000, SEEK_SET);
char string[] = "Hello, world";
write(fd, string, sizeof string);
close(fd);
}

其中您将以 1000013 字节文件结尾,但它仅使用一两个磁盘空间 block 。那是一个有洞的文件,其中在你写的字符串之前有1000000个零字节,系统不会在磁盘中为它分配 block 。只有当你在这些 block 上写入时,系统才会用新 block 填充你写入的部分以保存你的数据......但在那之前,系统会显示零字节,但它们不会存储在任何地方。

$ ll file
-rw-r----- 1 lcu lcu 1000013 4 jul. 11:52 file
$ hd file
[file]:
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 :................
*
000f4240: 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 00 :Hello, world.
000f424d
$ _

关于c - 有没有一种快速可靠的 POSIX 方法来检查当前文件偏移量是否在文件末尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56858983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com