深度理解:FindClose未调用导致的File内核对象的引用计数问题

深度理解:FindClose未调用导致的File内核对象的引用计数问题

作者:BlogUpdater |  时间:2017-04-21 |  浏览:2806 |  评论已关闭 条评论

应用程序启动后,不可避免的会使用到操作系统提供的文件系统API,比如CreateFile等。当我们有枚举文件或文件夹的需求时,会使用到系统提供的FindFirstFile/FindNextFile/FindClose函数族。
比如,如下的代码为枚举指定路径下所有的文件夹和文件:

void EnumerateFiles(LPCTSTR path)
{
    WIN32_FIND_DATA info;

    HANDLE hp = FindFirstFile(path, &info);
    do
    {
	    if (!((_tcscmp(info.cFileName, _T("."))==0) || (_tcscmp(info.cFileName, _T(".."))==0)))
	    {
		    if ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
		    {    
		    	    CString childFolderPath(_T(""));
		    	    childFolderPath.Format(_T("%s\\%s"), path, info.cFileName);
		    	    // Process child folder here
		    }
		    else
		    {
		    	    CString childFilePath(_T(""));
		    	    childFilePath.Format(_T("%s\\%s"), path, info.cFileName);
		    	    // Process child file here
		    }
	    }
    } while(FindNextFile(hp, &info)); 
    FindClose(hp);
}

当我们调用FindFirstFile后,应用程序会持有一个对路径path的FILE内核对象且该内核对象引用计数增至1,当调用FindClose后,该FILE内核对象的引用计数减1至0,系统自动释放该内核对象。
如果程序流程上有设计缺陷,导致while循环过早跳出而没有调用FindClose,这时应用程序不会释放持有的FILE内核对象,那么下次对该path路径的操作(比如在Windows资源管理器中浏览)时,就会因为内核对象引用计数的问题出现非预期的结果。

所以,结论是:在编码过程中,请确保FindFirstFile和FindClose成对调用,保持内核对象引用计数的一致性。

标签:

评论已关闭。