【问题标题】:C: open file before loop and close after or open/close within loop?C:在循环前打开文件并在循环后关闭或在循环内打开/关闭?
【发布时间】:2021-10-20 09:57:59
【问题描述】:

我有一个循环将处理后的数据写入文件。数据包含在一个链表中,并在一个迭代链表的 while 循环中写出。

我的问题是,我应该在 while 循环之前/之后打开/关闭写出文件,如下所示,还是应该在循环内移动打开/关闭,以便每次迭代打开然后关闭文件而不是保留在整个循环期间打开文件?

链表有数百 MB 的数据,可能有几个 GB。每次迭代都会写出不超过 80 个字符的行。这是在现代 linux 系统上运行的。

编辑:这不是嵌入式/关键系统。万一在关闭文件之前进程被中断,它将重新启动。

void msgs_output_to_file(Node *head) {
    Node *l = head;
    MsgType msg_type;

    char line[MAX_LINE_SIZE];

    FILE *file1 = NULL;
    FILE *file2 = NULL;

    file1 = fopen("file1.csv", "w");
    file2 = fopen("file2.csv", "w");

    while (l && l->data) {
        memset(line, 0, (size_t) MAX_LINE_SIZE);
        sprintf_msg(line, l->data);
        line[strlen(line)] = '\n'; // add new line

        msg_type = get_msg_type(l->data);
        switch (msg_type) {
            case TYPE_1:
                fputs(line, file1);
                break;
            case TYPE_2:
                fputs(line, file2);
                break;
            default:
                break;
        }
        l = l->next;
    }
    fclose(file1);
    fclose(file2);
}

【问题讨论】:

  • 打开文件的开销很大,因此在循环期间保持文件打开会更有效。
  • 我删除了 c++ 标签,因为在 c++ 中,解决方案看起来会大不相同。请仅标记您实际使用的语言
  • 第三种选择是每 N 行写入一个缓冲区。

标签: c linux


【解决方案1】:

一般规则是您应该只打开文件一次(如此循环)并在整个循环期间保持打开状态。理由是打开文件是一项相当昂贵的操作。

但是(对于任何一般规则)也有例外......重要的是您的程序在循环中间遇到了崩溃。如果后果只是您将不得不重新开始工作并且概率很低,那就继续吧。如果您正在处理任务关键数据,如果结果文件最终被破坏并且如果(无论是什么原因)崩溃是可以预料的,那么情况会有所不同。您必须在性能(只有一个打开/关闭)和稳健性之间取得平衡。至少您应该每 n 行刷新一次文件(n 是您可以接受丢失的最大行数),以尽量减少可能的数据丢失。

【讨论】:

  • 谢谢 - 是的,我在嵌入式系统工作,所以我理解你的意思。这是我在本地编写的用于处理一堆数据的“脚本”,我对非嵌入式系统没有太多经验。我认为在循环之外会更有意义,就像进程在中途中断一样,我将重新启动它。
【解决方案2】:

我对打开文件(在 Python 中)的理解是,您不会将整个文件加载到内存中,而是接收文件句柄。使用此文件句柄,您的脚本可以访问“高级”操作,例如读取和写入一行。向文件写入一行时,文件内容并不直接写入硬盘。相反,内容被放置在缓冲区中,当操作系统想要这样做时,或者当您使用 fclose() 关闭文件时,这些内容实际上是由操作系统写入文件的。

这种缓冲系统的优势在于,当你在循环中写入文件时,对硬盘的写入操作量是有限的,因为内容不是直接写入磁盘而是写入缓冲区。当缓冲区中有足够的内容或关闭文件时,缓冲区内容将写入磁盘。如果每次迭代都打开和关闭文件,则会增加对磁盘的写入操作次数并增加开销。

所以简短的回答是,我会在循环之前打开文件并在循环之后关闭文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多