我真的需要评论fclose()命令吗?

时间:2018-03-04 23:19:30

标签: c windows crt

以下程序取自Johnson M. Hart的 Windows系统编程(第四版):

#include<stdio.h>
#include<errno.h>

#define BUF_SIZE 256

int main(int argc, char *argv[])
{
    FILE *inFile, *outFile;
    size_t bytesIn, bytesOut;
    char rec[BUF_SIZE];

    if (argc != 3) {
        printf("Syntax : scp source destination.\n");
        return 1;
    }

    inFile = fopen(argv[1], "rb");
    if (inFile == NULL) {
        perror(argv[1]);
        return 2;
    }

    outFile = fopen(argv[2], "wb");
    if (outFile == NULL) {
        perror(argv[2]);
        //fclose(inFile);
        return 3;
    }

    while ((bytesIn = fread(rec, 1, BUF_SIZE, inFile)) > 0) {
        bytesOut = fwrite(rec, 1, bytesIn, outFile);
        if (bytesIn != bytesOut) {
            perror("Fatal write error.");
            //fclose(inFile); fclose(outFile);
            return 4;
        }
    }

    fclose(inFile);
    fclose(outFile);
    return 0;
}

无论是否关闭注释行中的文件,它的工作方式都相同 但是,在阅读了以前的帖子后,我不确定最佳做法是什么 让OS完成它的工作或在我认为应该的时候关闭它们。
我之所以这样说是因为我在Windows GUI应用程序中看到了这样的情况,当我关闭句柄而不是操作系统时,我在屏幕上引起了一个小故障,我实际上是在推迟操作系统,因为我像许多C ++书籍一样进行清理说。
我这里没有使用任何窗口......这是一个CRT实现,但仍然......

2 个答案:

答案 0 :(得分:2)

现代操作系统将释放不会释放的终止进程的资源,例如malloc已分配的内存,文件描述符等。因此理论上,如果您不需要关闭描述符无论如何都要结束这个节目。

但是你是对的,我认为这是不好的做法,我建议程序员总是释放资源并关闭文件描述符,即使是像你这样的小而琐碎的程序。稍后,当您在一个需要管理资源的更大项目中工作时,您可能会忘记在真正需要时进行清理,因为您从琐碎的例子中学到了不关心它。这就是为什么我认为即使像你这样的琐碎例子也是如此。

  

我之所以这样说是因为我在Windows GUI应用程序中看到的情况是当我关闭句柄而不是操作系统时,我在屏幕上造成了一个小故障,我实际上是在推迟操作系统,因为我像许多C ++一样进行清理书说。

我不知道这一点,也许你正在关闭错误的文件描述符(或者你不应该关闭的文件描述符)或者错误的时间。没有代码,很难说这是否属实。

答案 1 :(得分:1)

如果整个程序在fclose之后结束,那么它并没有真正有所作为。但是,通常情况并非如此。你经常打开一个文件写入它,如果你不关闭它,那么你将无法重新打开它,也不会有任何其他程序能够这样做。另外,如果您只是继续打开文件,那么当操作系统需要关闭所有文件时,终止时会有很大的开销。然而,如果你在不再需要它们时将它们关闭,那么在程序运行的过程中它会随着时间的推移而均匀分布。

把它想象成在图书馆里。如果你从书架上拿出一堆书并且不要把它们放回去,而不是让任何事情真的发生,因为图书管理员会把它们放回去(虽然他会被它占用很长一段时间)。然而,如果你拿了一堆书而不使用它们而你只是把它们堆放在你的桌子上并且你不会离开很长一段时间,而不是所有那些时候图书馆里的其他人都不能使用它们。

即使你的程序终止使用fclose的原因是可伸缩性,因为如果你没有,然后你改进它,或者在其他程序等中使用它作为一个函数,那么所有那些遗漏的fcloses将会来回来咬你的屁股。 此外,它也更安全,因为如果你关闭它,它就不会被意外写入或读取。如果您没有在多个人使用相同代码的专业环境中工作,但防御性编程是一个非常有用且必不可少的工具,那可能看起来很愚蠢。