3

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

4

7 回答 7

2

您可能最好进行一次打开和一次关闭。不停的开/关会导致大量的IO浪费。

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

请确保最终关闭文件。

于 2010-09-15T17:59:29.163 回答
1

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

我建议你做那个 AppendFile 函数。它将简化写入过程,并且您将能够比使用一堆 fwrite() 更轻松地更改文件句柄。

于 2010-09-15T18:00:22.297 回答
1

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

If the writes will be infrequent, open/append/close is a better idea IMO -- but AppendFile could be made to work with an already open file handle, so it actually works better either way.

Add to that, if you use threads at all, you don't want random writes to the file -- you want to have some way to synchronize them. Having an AppendFile or similar function gives you that synchronization point -- you can add code in there to wait til another thread's finished. Just try doing that when you're directly writing to the file in a hundred different places.

于 2010-09-15T18:01:31.717 回答
1

Sometimes a database is a very good substitute for text files, expecially when the database was specifically designed to replace text files in the first place :)

Take a look at SQLite ( http://www.sqlite.org/ ).

Think of SQLite not as a replacement for Oracle but as a replacement for fopen()

于 2010-09-15T18:24:06.987 回答
1

global variables are usually not a good thing. For small programs it's doesn't matter though.

While still using a global file handle, consider accessing it only through a void AppendFile(char *data_to_append); function, where only AppendFile references the global file, instead of scattering it all over your code.

Opening/closing a file on every access can be a vaste if the file is accessed often.

Also, file handles are normally closed when your program ends (either dies, or exits normally), so you're not leaking anything if your program crashes.

于 2010-09-15T18:32:11.520 回答
0

是的。

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

于 2010-09-15T17:59:56.307 回答
0

If by file handle you mean a FILE * then opening at the beginning and closing at the end with lots of users should work as expected even if there are multiple threads as long as you do your writes with single stdio function calls on POSIX systems.

If by file handle you mean an integer returned by the operating system's open call then these are usually thread safe within a single call to write (or similar) since the operating system will lock the file while transferring data to buffers associated with that file.

If the program is a single threaded application then you don't have much to worry about either way.

If you were to go with repeatedly opening, appending, and closing the file you could run into trouble if using stdio's FILE * with multiple threads or if calls to AppendFile were somehow made recursively because the different FILE *s would not share buffers within the application and so as the file changed in one thread other threads might overwrite those changes.

A similar thing can happen with os file handles (integers returned by open) since the different calls to open will produce different file handles with will not share their seek position, so as the file grew the different file descriptors would end up with seek positions that weren't actually at the end of the file unless you can open the file in append only mode ( O_APPEND ) where the OS handles this for you.

Opening and closing the file over and over does generate a lot of extra work, either way.

于 2010-09-15T18:26:31.667 回答