我正在编写单元测试,并试图找到一种方法来测试我的类是否已正确关闭文件句柄(它使用旧式open()和关())。理想情况下,我希望能够在不访问实际句柄的情况下执行此操作 - 我希望能够检查文件系统中的文件并确定它是否当前在其他地方打开。如何确定文件是否已关闭
我试过通过独占文件锁来做它,但我没有多少运气。此外,文件锁定非常不跨平台(这需要在Solaris,Linux和Windows上运行)。
有什么建议吗?
我正在编写单元测试,并试图找到一种方法来测试我的类是否已正确关闭文件句柄(它使用旧式open()和关())。理想情况下,我希望能够在不访问实际句柄的情况下执行此操作 - 我希望能够检查文件系统中的文件并确定它是否当前在其他地方打开。如何确定文件是否已关闭
我试过通过独占文件锁来做它,但我没有多少运气。此外,文件锁定非常不跨平台(这需要在Solaris,Linux和Windows上运行)。
有什么建议吗?
如果你依赖于打开/关闭这样的文件,这不是一个适当的单元测试 - 这种测试可能由于各种原因而随机失败,从而导致误报和普遍混淆。
相反,考虑抽象文件操作并确保在文件的表示形式上调用close。
无法检查文件句柄是否仍然打开。
如果你使用C++,你可以简单地总是使用RAII,你不必担心未关闭的文件句柄。
否则,你永远不能调用系统API,而是调用你的包装器API。每当你打开你可以添加一个向量的路径,你关闭你的一切都可以删除该路径。最后,检查你的矢量是否有零大小。
您可以用select
和poll
查询。选择将返回EBADF
如果文件描述符被关闭:
fd_set rfds;
struct timeval tv = { 0, 1 };
int retval;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval == -1 && errno == EBADF)
// File is closed
注意,我已经没有测试代码,但文档讲述了这一点。
此外,这并不完全准确,因为errno也可能是EBADF,原因不同。
编辑:另一件事:如果你在关闭另一个文件后立即打开一个文件,它很可能与前一个文件具有相同的fd,所以如果你想检查是否所有文件都已关闭,这只能用于半体面。
当然,如果文件已关闭,但是另一个文件已打开并碰巧被分配了相同的文件描述符(这很可能,在给定文件描述符分配策略的情况下),这将不起作用。 – 2010-12-14 00:08:10
@亚当是的,但不能真正帮助。但是,如果它只是想检查是否所有文件都已关闭,那么它就可以工作。但我会添加它,谢谢。 – terminus 2010-12-14 00:09:34
在Unix/Solaris/Linux中,如果您知道pid,则可以检查/proc/
pid /fd/*
。您也可以扫描所有/ proc/*/fd条目。
对于Windows,我会研究一下sysinternals.com工具ProcMon,现在叫做Process Monitor。我不记得是否曾经有可用的源代码。
如果您想知道某个文件系统中的给定文件是否由该机器上的某个进程打开,那么有一个有用的工具叫做lsof,它可以告诉您各种unix和unix系统。
点好。 – 2010-12-14 15:52:07