附加到全局文件句柄,是不是很糟糕?

时间:2010-09-15 17:54:27

标签: c filehandle

让我们说我的程序中有多个函数需要将数据附加到某个文件。我使用全局文件句柄在程序开头打开文件,这样我就可以在任何需要的地方附加到它。 (注意,我知道我可以将文件句柄作为参数传递给函数,但这不是这个问题的目的)。在程序开头打开文件句柄,然后在结束时关闭它是不是很糟糕;或者更好的是有一个函数说void AppendFile(char *data_to_append);然后打开文件并附加到它并在同一个函数中关闭它?如果程序死了,FD仍然在使用中是我看到的唯一不好的事情,但同时如果你使用该功能,你会打开和关闭相同的文件数百次和数百次。

7 个答案:

答案 0 :(得分:2)

你可能最好做一次开放和一次关闭。打开/关闭不停止将导致大量浪费的IO。

您可能希望使用互斥锁保护此功能,因此一次只能有一个线程写入文件句柄。

请确保最终关闭文件。

答案 1 :(得分:1)

如果您的程序是单线程的,那没关系。如果它在文件句柄打开时死亡,它可能会被操作系统关闭。如果不是,那么保证它不会在你的AppendFile函数中消失?

我建议你做一下AppendFile函数。它将简化写入过程,并且您可以更轻松地更改文件句柄的内容,而不是使用一堆fwrite()。

答案 2 :(得分:1)

取决于您对文件的关注程度不会导致数据丢失或丢失。如果程序崩溃,则无法保证尚未完成的所有写入(不仅仅是完成,而是刷新并提交到磁盘)会发生什么。如果存在未提交的写入,则可以将其丢弃或完成一半。关闭文件可以保证提交这些写入。

如果写入不频繁,打开/追加/关闭是一个更好的主意IMO - 但AppendFile可以使用已经打开的文件句柄,所以它实际上更好地工作。

除此之外,如果您根本使用线程,则不希望随机写入文件 - 您希望有一些方法来同步它们。拥有AppendFile或类似功能可以为您提供同步点 - 您可以在其中添加代码以等待另一个线程完成。当你在一百个不同的地方直接写文件时,试着这样做。

答案 3 :(得分:1)

有时数据库是文本文件的非常好的替代品,特别是当数据库专门设计为首先替换文本文件时:)

看一下SQLite(http://www.sqlite.org/)。

  

认为SQLite不是Oracle的替代品,而是替代fopen()

答案 4 :(得分:1)

全局变量通常不是一件好事。对于小程序来说,这并不重要。

虽然仍在使用全局文件句柄,但请考虑仅通过void AppendFile(char *data_to_append);函数访问它,其中只有AppendFile引用全局文件,而不是将其全部分散在代码上。

如果经常访问文件,则在每次访问时打开/关闭文件都可能是一种恶意。

此外,文件句柄通常在程序结束时关闭(死亡或正常退出),因此如果程序崩溃,您不会泄漏任何内容。

答案 5 :(得分:0)

不是最有帮助的答案,但我担心你的问题过于笼统而模糊,不能给你任何详细的信息。如果您通过程序访问此FD,则表明您的高级设计存在问题。这些单独的访问是否以某种方式相互关联?它们可以组合成少量访问文件的点吗?你的程序中是否有某种隐含的数据结构可以更好地在类中实现?

答案 6 :(得分:0)

如果通过文件句柄你的意思是FILE *然后在开头打开并在结束时关闭大量用户应该按预期工作,即使有多个线程,只要你用单一stdio函数进行写操作调用POSIX系统。

如果通过文件句柄表示操作系统的打开调用返回的整数,那么这些通常是在write(或类似)的单个调用中是线程安全的,因为操作系统将在传输数据时锁定文件与该文件关联的缓冲区。

如果程序是单线程应用程序,那么您无需担心任何一种方式。

如果你要反复打开,追加和关闭文件,如果使用带有多个线程的stdio FILE *或者以某种方式对AppendFile的调用是以递归方式进行的,那么你可能会遇到麻烦FILE *不会在应用程序中共享缓冲区,因此在一个线程中更改文件时,其他线程可能会覆盖这些更改。

os文件句柄(open返回的整数)也会发生类似的事情,因为对open的不同调用将产生不同的文件句柄而不会共享其搜索位置,因此文件增长了不同的文件描述符最终会找到实际上不在文件末尾的搜索位置,除非您可以在仅附加模式(O_APPEND)中打开文件,操作系统会为您处理此文件。

无论如何,一遍又一遍地打开和关闭文件会产生许多额外的工作。