如何判断一个文件是否被关闭?
2012-06-16 21:59
417 查看
做项目的时候遇到了下面这个问题:如何判断一个打开的txt文件是否被关闭?
在打开一个txt文件的时候,notepad程序是自动通过文件路径的参数首先复制文件,然后马上就关闭了文件通道,这个时候打开的其实只是notepad程序而不是文件本身。文件本身的打开与关闭是一瞬间的事情。也就是说notepad程序在读取了文件以后就马上将文件关闭了。(不知道这样讲对不对,还请大家指正。)
那么我们判断一个txt文件是否被关闭其实就是判断这个notepad这个进程是否关闭。
所以一开始自己想是不是要判断进程是否被关闭。这样一来还得遍历进程判断notepad程序...而且进程名称全部都是notepad, 难道还要通过获取进程ID的方法吗?。。。。
这个方式似乎比较复杂,然后自己百度了一把看看还有没有什么更好的办法。
最后找到了下面这个方法:
http://topic.csdn.net/t/20030804/05/2104986.html
利用Windows API判断文件共享锁定状态
锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据。要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定数据是否可读或可写,从而为开发出健壮的程序提供切实依据。
同样,在Windows中,文件可以共享模式打开,它也涉及到锁的操作问题。根据Windows中文件共享时加锁范围的大小,锁可分为全局锁和局部锁;全局锁以锁定文件全部内容为特征,而局部锁以锁定文件的局部内容为特征,且文件的锁定区域不可重复。根据Windows中文件共享时锁的操作权限分类,锁可分为:读锁,写锁,读写锁(可读可写,全局锁)。
利用上述文件中锁的区域不可重复的特性,我们可尝试给指定文件加一全局锁。若加锁成功,说明指定文件未被其它进程锁定;否则,说明有其它进程锁定了该文件。这里,我们利用两个Windows Api文件操作函数:OpenFile和CreateFile来实现锁定状态的判断。
具体对CreateFile的第三个参数的共享模式认识还不是很深刻。。。回头再好好看看windows核心编程。。。
接着上几天的那个问题。
以前都是用WinExec或者是system函数创建的子进程,这次用CreateProcess来获得它的句柄。
CreateProcess函数。这个函数有10个参数。汗~~~~。其实我们主要用到的就是第一个参数,第二个参数,还有最后一个参数。
第一个参数是要打开的应用程序的路径,第二个参数是命令行参数。最后一个参数是用来返回新创建的进程的句柄。
自己仔细看了一下《windows核心编程》这本书。但是不怎么看的懂。。。因为毕竟10个参数要全部看懂的话就比较困难的。
这段代码的前面初始化部分是copy《windows核心编程》的。参数LPSTR NewFilePath 是文件的路径名称。
然后这个函数返回一个新创建的进程的句柄
下面是WaitForSingleObject这个函数原型:
DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
这个函数很简单,第一个参数就是句柄,第二个参数是等待多少时间(以毫秒计算)。这样就达到了阻塞的效果。
如果是INFNITE,就是等到进程终止的时候才进行下面的代码,否则就一直阻塞等待。
这样一来问题就很好的解决了。
如果是直接用notepad打开某个文件,怎么知道它关闭了呢?其实思路应该还是跟上面的一样,就是首先获得这个进程的句柄,判断这个句柄是否存在,如果不存在,那么应该就是结束了。
接下来再来解决上篇博客里写的那个问题。我首先用notepad文件打开一个.txt文件。然后再用CreateFile打开这个文件,并且设置第三个参数为0,就是设置共享模式为不共享,这个时候使用CreateFile能打开文件并且获得一个句柄,这就说明这个时候notepad程序已经关闭了.txt文件。
不知道自己讲的对不对,有什么错误还恳请大家指正。
在打开一个txt文件的时候,notepad程序是自动通过文件路径的参数首先复制文件,然后马上就关闭了文件通道,这个时候打开的其实只是notepad程序而不是文件本身。文件本身的打开与关闭是一瞬间的事情。也就是说notepad程序在读取了文件以后就马上将文件关闭了。(不知道这样讲对不对,还请大家指正。)
那么我们判断一个txt文件是否被关闭其实就是判断这个notepad这个进程是否关闭。
所以一开始自己想是不是要判断进程是否被关闭。这样一来还得遍历进程判断notepad程序...而且进程名称全部都是notepad, 难道还要通过获取进程ID的方法吗?。。。。
这个方式似乎比较复杂,然后自己百度了一把看看还有没有什么更好的办法。
最后找到了下面这个方法:
http://topic.csdn.net/t/20030804/05/2104986.html
利用Windows API判断文件共享锁定状态
锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据。要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定数据是否可读或可写,从而为开发出健壮的程序提供切实依据。
同样,在Windows中,文件可以共享模式打开,它也涉及到锁的操作问题。根据Windows中文件共享时加锁范围的大小,锁可分为全局锁和局部锁;全局锁以锁定文件全部内容为特征,而局部锁以锁定文件的局部内容为特征,且文件的锁定区域不可重复。根据Windows中文件共享时锁的操作权限分类,锁可分为:读锁,写锁,读写锁(可读可写,全局锁)。
利用上述文件中锁的区域不可重复的特性,我们可尝试给指定文件加一全局锁。若加锁成功,说明指定文件未被其它进程锁定;否则,说明有其它进程锁定了该文件。这里,我们利用两个Windows Api文件操作函数:OpenFile和CreateFile来实现锁定状态的判断。
具体对CreateFile的第三个参数的共享模式认识还不是很深刻。。。回头再好好看看windows核心编程。。。
接着上几天的那个问题。
以前都是用WinExec或者是system函数创建的子进程,这次用CreateProcess来获得它的句柄。
CreateProcess函数。这个函数有10个参数。汗~~~~。其实我们主要用到的就是第一个参数,第二个参数,还有最后一个参数。
BOOL WINAPI CreateProcess( __in_opt LPCTSTR lpApplicationName, __inout_opt LPTSTR lpCommandLine, __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCTSTR lpCurrentDirectory, __in LPSTARTUPINFO lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation );
第一个参数是要打开的应用程序的路径,第二个参数是命令行参数。最后一个参数是用来返回新创建的进程的句柄。
自己仔细看了一下《windows核心编程》这本书。但是不怎么看的懂。。。因为毕竟10个参数要全部看懂的话就比较困难的。
HANDLE OpenNewFile(LPSTR NewFilePath) { STARTUPINFOA si = { sizeof(si) }; SECURITY_ATTRIBUTES saProcess, saThread; PROCESS_INFORMATION piProcess; saProcess.nLength = sizeof(saProcess); saProcess.lpSecurityDescriptor = NULL; saProcess.bInheritHandle = TRUE; saThread.nLength = sizeof(saThread); saThread.lpSecurityDescriptor = NULL; saThread.bInheritHandle = FALSE; CHAR Command[100]; strcpy(Command, "notepad.exe "); strcat(Command, NewFilePath); BOOL fRet =CreateProcessA("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE", Command, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &piProcess); if(fRet == TRUE) return(piProcess.hProcess); return 0; }
这段代码的前面初始化部分是copy《windows核心编程》的。参数LPSTR NewFilePath 是文件的路径名称。
然后这个函数返回一个新创建的进程的句柄
HRes = OpenNewFile(NewFilePath);// 获得创建新进程打开notepad文件的句柄 WaitForSingleObject(HRes, INFINITE);
下面是WaitForSingleObject这个函数原型:
DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
这个函数很简单,第一个参数就是句柄,第二个参数是等待多少时间(以毫秒计算)。这样就达到了阻塞的效果。
如果是INFNITE,就是等到进程终止的时候才进行下面的代码,否则就一直阻塞等待。
这样一来问题就很好的解决了。
如果是直接用notepad打开某个文件,怎么知道它关闭了呢?其实思路应该还是跟上面的一样,就是首先获得这个进程的句柄,判断这个句柄是否存在,如果不存在,那么应该就是结束了。
接下来再来解决上篇博客里写的那个问题。我首先用notepad文件打开一个.txt文件。然后再用CreateFile打开这个文件,并且设置第三个参数为0,就是设置共享模式为不共享,这个时候使用CreateFile能打开文件并且获得一个句柄,这就说明这个时候notepad程序已经关闭了.txt文件。
不知道自己讲的对不对,有什么错误还恳请大家指正。
相关文章推荐
- 【转载】如何在shell中判断一个文件是否为空
- 如何快速判断一个文件是否为病毒
- 如何列出某个目录下的所有子目录? 3)如何判断一个文件或目录是否存在? 4)如何读写文件?
- makefile中如何判断一个文件是否存在
- bash如何判断一个文件是否存在
- 如何判断一个文件或目录是否存在
- makefile中如何判断一个文件是否存在
- 如何判断一个文件是否为病毒
- 如何在shell中判断一个文件是否为空
- nodejs如何判断一个文件、文件夹是否存在
- 如何判断一个文件是否结束?
- 如何判断一个文件是否是win32可执行文件
- C#中如何判断一个文件是否存在
- C语言判断一个文件是否存在,以及如何删除
- batch文件中如何判断一个变量是否存在 (注意不是变量是否有值)
- java如何判断一个linux下的文件是否为链接文件。
- 如何判断一个文件是否正在被使用
- 如何在shell中判断一个文件是否为空
- 如何判断一个文件是否存在
- windows10UWP:如何判断一个文件或者文件夹是否存在?