开发者社区> 问答> 正文

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

如何使用底层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反映实际大小而不反映磁盘文件大小,即不包括内核缓冲的数据?

另一个想法是使用

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

但这似乎不是快速而适当的方法。

同样,这两种方法似乎都不是原子的,因此,如果在文件后追加了另一个进程,则可以在检查当前偏移量后更改大小。

展开
收起
祖安文状元 2020-01-06 16:01:05 395 0
1 条回答
写回答
取消 提交回答
  • 但是,是否st->st_size反映实际大小而不反映磁盘文件大小,即不包括内核缓冲的数据?

    我不明白您对内核缓冲数据的意思。中的数字st->st_size反映了文件的大小(以字符为单位)。因此,如果文件包含1000000字符,则数字st->st_size将为1000000,字符位置为0到999999。

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

    做一个off_t saved = lseek(fd, 0, SEEK_END);,它返回实际位置(您必须保存它,以便以后恢复它),然后执行第二次调用off_t file_size = lseek(fd, saved, SEEK_SET);,返回到您之前的位置,但是返回一个数字来返回您之前的位置(这是该位置的最后一个位置)文件,最后一个字符之后)。如果选中此选项,它将与所返回的值匹配st->st_size。 stat(2)对文件描述符执行a 以获得您提到的值。 如果您有多个线程或进程与您共享文件描述符(通过dup(2)系统调用或fork()ed进程),如果它们在您的两个调用之间执行,或调用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字节文件结尾,但仅使用一两个磁盘空间块。那是一个空洞的文件,其中1000000您写入的字符串之前有零个字节,并且系统不会在磁盘中为其分配块。只有在这些块上进行写操作时,系统才会用新的块填充您写的部分以保存数据...但是直到那时,系统将向您显示零字节,但它们不会存储在任何地方。

    $ 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
    $ _
    
    2020-01-06 16:01:18
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载