VC++判断目标文件是否被独占(附源码)
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++判断目标文件是否被独占(附源码)相关的知识,希望对你有一定的参考价值。
在IM软件中发起文件发送时,如果要发送的是某word文件,并且该word文件被office打开,则会提示文件正在被占用无法发送,如下所示:
那文件被占用到底是如何判断出来的呢?其实很简单,调用系统API函数CreateFile,打开该文件(OPEN_EXISTING),传入FILE_SHARE_READ共享读标记位,如果文件被占用,则文件会打开失败。
1、判断文件被占用的代码
判断文件被占用的接口函数 IsFileOccupiedByOtherProgram,实现如下:
BOOL IsFileOccupiedByOtherProgram( const CString& strFilePath )
// 检测的办法是通过研究某软件的文件传输表现现象来确定的
HANDLE hFile = CreateFile( strFilePath,
GENERIC_READ,
FILE_SHARE_READ, // 读共享,但写不共享,如果有程序正在占用着文件写,则该函数会返回失败
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hFile != INVALID_HANDLE_VALUE )
CloseHandle( hFile ); // 文件打开成功,此处必须将句柄关闭,以释放对文件的占用
return FALSE; // 获取到文件句柄,文件没被占用
else
return TRUE; // 没有获取到文件句柄,文件可能被占用
2、判断文件夹中是否有被占用的文件
发起文件传输时,可能是要传一个文件夹,我们要判断文件夹中是否有文件被占用。封装的接口HasFileOccupieddByOtherProgram中一是递归调用本接口,二是调用对单个文件判断的接口IsFileOccupiedByOtherProgram。HasFileOccupieddByOtherProgram接口实现如下:
// 判断文件夹中是否有文件在被其他程序占用(其他程序可能占用着该程序并可能对程序进行写入操作,比如doc文档被WORD打开)
// 如果有被占用的文件,函数即退出
// 参数说明:strFolderDirp[in], bHasFilebOccupied[out], strbOccupiedFilePath[out]
void HasFileOccupieddByOtherProgram( const CString& strFolderDir, BOOL& bHasFilebOccupied, CString& strOccupiedFilePath )
CString strFindFileName = strFolderDir + _T("\\\\*.*");
WIN32_FIND_DATA wfd;
HANDLE hFindFile = FindFirstFile( strFindFileName, &wfd );
if ( hFindFile == INVALID_HANDLE_VALUE )
return;
while ( 1 )
if ( bHasFileOccupied ) // 有文件被占用,则直接结束循环
break;
// 将文件夹中的.和..过滤掉,之前仅判断wfd.cFileName[0]是否为‘.’是有问题的,
// 比如版本控制的代码的目录下包含掩藏的.svn文件夹,会导致文件夹大小计算有误
//(偏小)
if ( _tcscmp( wfd.cFileName, _T(".") ) != 0 &&
_tcscmp( wfd.cFileName, _T("..") ) != 0 )
// 非本级或上级目录
CString strFilePath = strFolderDir + _T('\\\\') + wfd.cFileName;
if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
// 目录
// 递归
HasFileOccupieddByOtherProgram( strFilePath, bHasFilebOccupied , strbOccupiedFilePath );
else
// 文件
BOOL bOccupied = IsFileOccupiedByOtherProgram( strFilePath ); // 检测当前文件是否正被其他程序占用
if ( bOccupied )
bHasFileOccupied = true;
strbOccupiedFilePath = wfd.cFileName;
break;
if ( !FindNextFile( hFindFile, &wfd ) )
break;
FindClose( hFindFile );
return;
3、再做一次封装,同时支持对文件和文件夹的判断
调用该接口IsTargetFileOccupied时传入文件或文件夹的路径,然后指明当前判断对象是文件还是文件夹,如下:
// 判断被拖动的文件或文件夹中的文件是否在被其他程序占用(其他程序可能占用着该程序
// 并可能对程序进行写入操作,比如doc文档被WORD打开)
BOOL IsTargetFileOccupied( const CString& strFilePath, const EmFilePathType emFilePathType )
if ( emFilePathType <= emInvalideType || emFilePathType > emFile )
return FALSE;
BOOL bFileOccupied = false;
CString strMsg;
if ( emFile == emFilePathType ) // 单个文件
bFileOccupied = IsFileOccupiedByOtherProgram( strFilePath );
if ( bFileOccupied )
else // 文件夹
CString strOccupiedFileName;
HasFileOccupieddByOtherProgram( strFilePath, bFileOccupied , strOccupiedFileName);
if ( bFileOccupied )
return bFileOccupied ;
以上是关于VC++判断目标文件是否被独占(附源码)的主要内容,如果未能解决你的问题,请参考以下文章
VC++获取系统TCPUDP端口使用信息,并判断端口是否被占用(附源码)
VC++检测防火墙是否开启判断程序是否加入防火墙白名单(附源码)