我有一个将处理过的数据写入文件的循环。数据包含在一个链表中,并在迭代链表的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);
}
一般规则是,您应该只打开文件一次(因此在循环之外),并在整个循环期间保持打开状态。理由是打开文件是一个相当昂贵的操作。
但是(就一般规则而言)也有例外……重要的是,如果程序在循环中出现崩溃,会发生什么。如果后果只是你必须重新开始工作,而且可能性很低,那就继续前进吧。如果您正在处理关键任务数据,如果结果文件最终被破坏,并且(无论原因是什么)预计会崩溃,那么情况将有所不同。您必须处理性能(只有一个打开/关闭)和健壮性之间的平衡。至少您应该每n行刷新一次文件(n是您可以接受丢失的最大行数),以尽量减少可能的数据丢失。
我对打开文件(在Python中)的理解是,您不将整个文件加载到内存中,而是接收一个文件句柄。使用这个文件句柄,您的脚本可以访问"高层"。像读写一行这样的操作。当向文件写入一行时,文件内容不会直接写入硬盘。相反,内容被放在一个缓冲区中,当操作系统认为需要这样做时,或者当您使用fclose()关闭文件时,内容实际上由操作系统写入文件。
这个缓冲区系统的优点是,当您在循环中写入文件时,对硬盘的写入操作数量是有限的,因为内容不是直接写入磁盘,而是写入缓冲区。然后,当缓冲区中有足够的内容或关闭文件时,将缓冲区内容写入磁盘。如果每次迭代都打开和关闭文件,就会增加对磁盘的写操作次数,从而增加开销。
所以简短的回答是,我会在循环之前打开文件,在循环之后关闭文件。