【问题标题】:How to detect, whether a FILE object is closed?如何检测 FILE 对象是否已关闭?
【发布时间】:2013-02-28 01:49:08
【问题描述】:

请看下面的代码块,我如何确保一个 FILE 对象在我调用 fclose 之前没有关闭? 顺便说一句,两次调用 fclose 是否安全?

    FILE* f = fopen('test.txt')

    //some code here, f may be closed by someone, but they may not set it to NULL
    ...


    /// I want to make sure f is not closed before, how can I do it here?
    if(...)
    {
       fclose(f)
    }

【问题讨论】:

  • 你用的是什么编译器?
  • @Aniket 我正在使用 gcc

标签: c fclose


【解决方案1】:

不,您必须自己跟踪。这类似于判断指向已分配块的指针是否已被释放的问题。由于指针不再有效,因此无法进行此类测试。这同样适用于FILE *。关闭文件后,任何访问底层对象的尝试都会导致未定义的行为。

更新:

注意,引用 Linux 手册页:

如果流参数是
非法指针,或者是已经传递给先前调用的描述符
fclose() 的阳离子。

请记住,未定义的行为并不意味着它会崩溃或它不会“工作”。这意味着不保证任何特定的行为并且操作是不安全的。在fclose() 之后访问FILE 结构是一个非常糟糕的主意。

【讨论】:

    【解决方案2】:

    每当您在程序中的任何位置调用 fclose() 时,都应将 FILE* 文件指针设置为 NULL,如下所示,您可以稍后在文件末尾的清理过程中检查。

    fclose(f)
    f = NULL;
    

    文件末尾的清理部分如下所示:

    if (f != NULL)
    {
        fclose(f);
        f = NULL;
    }
    

    【讨论】:

    • 如果他不确定文件是否已关闭怎么办?
    • 需要调用 fclose(FILE*) (即使文件被删除)来刷新缓冲区以及释放在打开文件句柄的过程中分配的任何簿记。跟踪 FILE* 句柄是程序的责任。
    • R. 所说的;如果它是关闭的,而他在打开它后不知道,那么就存在严重错误。文件系统不会打开或关闭文件,读取流的代码会。
    • +1 是唯一的便携式解决方案。但是对于这个答案中的例子:fclose()可能会失败,所以还要检查它的返回值,就像 每个 系统调用一样。
    【解决方案3】:

    粘贴android-bionic的fclose源代码:(fclose.c文件)

    int fclose(FILE *fp)
    {
        int r;
    
        if (fp->_flags == 0) {  /* not open! */
            errno = EBADF;
            return (EOF);
        }
        FLOCKFILE(fp);
        WCIO_FREE(fp);
        r = fp->_flags & __SWR ? __sflush(fp) : 0;
        if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
            r = EOF;
        if (fp->_flags & __SMBF)
            free((char *)fp->_bf._base);
        if (HASUB(fp))
            FREEUB(fp);
        if (HASLB(fp))
            FREELB(fp);
        fp->_r = fp->_w = 0;    /* Mess up if reaccessed. */
        fp->_flags = 0;     /* Release this FILE for reuse. */
        FUNLOCKFILE(fp);
        return (r);
    }
    

    在关闭的 FILE 对象上调用 fclose 似乎是安全的。

    【讨论】:

    • “在关闭的 FILE 对象上调用 fclose 似乎是安全的。” ...好吧...不幸的是它不是。你可以不系安全带开车,你可能不会卷入事故,但这并不意味着它是安全的。
    • @dreamlax,那么调用 fclose 两次会有什么不好的后果?
    • @Patrick:如果没有更多的实现知识,很难说,但请注意评论说文件正在被释放以供重用。想象一下,在您的第二个 fclose() 调用之前,另一个 fopen() 调用重用了相同的 FILE 结构。现在你不小心关闭了另一个文件,哎呀......
    • 任何编写了 fclose() 版本但不具有此 flags 变量测试等效项的程序员与不能记住文件是否已关闭。顺便说一句,应该为认为“r”是一个很好的变量名的人保留一些空间。
    • 除了android之外还有一些其他的世界。所以这根本不是证据。
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多