★★★一个有点难度的检查文件被打开的问题,请高人进来指点一下★★★

linuxyf 2008-04-28 11:23:01
我需要检查一个文件夹是否有文件已被打开,我采用的是遍历打开检查方法,就是遍历打开这个文件夹下的每一个文件,如果有文件不能打开,则该文件已经被打开。

但是这样有一个问题,当我的文件夹下面的文件很多的时候,这个检查时间就会很长。

若是我移动这个文件文件夹,那么操作系统会很快检查到是否有文件被打开,操作系统是如何做到这种快速检查的??我如何做才能提高这种检查速度??

请高人指点,不胜感激!
...全文
268 点赞 收藏 37
写回复
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
rageliu 2008-04-30
这个问题,我一直认为还是ifs ddk文件过滤驱动最彻底
回复
以后需再关注,现在先帮你顶一下
回复
9CNR1 2008-04-29
路过
回复
duanhuicen 2008-04-29
不用做驱动,做个文件监视的就可以了。指定监视指定文件夹下的所有文件,包括子文件夹。这样如果无论是任何一个文件被删除,创建,打开,修改你都能知道了
回复
cnzdgs 2008-04-29
驱动程序也可以用这种办法,用ZwCreateFile打开目录,然后用ZwSetInformationFile的FileRenameInformation功能。
回复
linuxyf 2008-04-29
[Quote=引用 28 楼 cnzdgs 的回复:]
你是在两个盘之间移动?不然不会有移动一半的情况。如果这样你可以先把目录改名,如果失败则提示无法移动,如果成功再移动到目标位置。
[/Quote]

这也不失为一个应用层的解决方案。
回复
KeSummer 2008-04-28
举个例子来看看??例如。。。
回复
Kudeet 2008-04-28
[Quote=引用 17 楼 KeSummer 的回复:]
引用 15 楼 laiyiling 的回复:
引用 5 楼 KeSummer 的回复:
如果一文件或者文件夹被打开,必定有handle存在,
用ZwQuerySystemInformation加SystemHandleInformation可以拿到整个系统所打开的handle,
然后判断handle的类型为file时则查询object的名字,即可获得整个系统内打开的文件以及文件夹。



这也只是可行,在一些Corner case,他的速度估计和楼主自己的遍历差不多!


ZwQuerySystemInformation…
[/Quote]


注意,在Corner case,我并没有说所有的情况啊!
回复
Kudeet 2008-04-28
[Quote=引用 2 楼 linuxyf 的回复:]
没说清楚,是以独占的方式打开
[/Quote]

to cnzdgs,

楼主自己说过是以独占方式打开的. :)
回复
missye1437 2008-04-28
近来学习学习知识
回复
KeSummer 2008-04-28
[Quote=引用 15 楼 laiyiling 的回复:]
引用 5 楼 KeSummer 的回复:
如果一文件或者文件夹被打开,必定有handle存在,
用ZwQuerySystemInformation加SystemHandleInformation可以拿到整个系统所打开的handle,
然后判断handle的类型为file时则查询object的名字,即可获得整个系统内打开的文件以及文件夹。



这也只是可行,在一些Corner case,他的速度估计和楼主自己的遍历差不多!
[/Quote]

ZwQuerySystemInformation直接从句柄表里面取数据,然后直接从对象头查到object name。
假设有两个文件:
c:\aa\bb.txt
c:\aa\bb\cc.txt
打开。直接就返回上面两个个字符串,整个过程只涉及查表,比LZ的速度要快多了。很明显 15L 的说法是错的。按照15L的推理,那么process explorer运行起不是要半天?事实上用process explorer查看进程打开的文件只是瞬间。
回复
cnzdgs 2008-04-28
个人认为,只能是逐个句柄判断。

假设一个文件以完全共享方式打开,并且没有申请读、写、删除权限,此时是可以以独占方式被再次打开的;
假设一个文件以共享删除方式打开,是可以被删除和移动的;
用监视方法只能监视文件改变,并不能监视文件打开。
回复
Kudeet 2008-04-28
[Quote=引用 5 楼 KeSummer 的回复:]
如果一文件或者文件夹被打开,必定有handle存在,
用ZwQuerySystemInformation加SystemHandleInformation可以拿到整个系统所打开的handle,
然后判断handle的类型为file时则查询object的名字,即可获得整个系统内打开的文件以及文件夹。
[/Quote]


这也只是可行,在一些Corner case,他的速度估计和楼主自己的遍历差不多!
回复
rotApple 2008-04-28
引用
如果一文件或者文件夹被打开,必定有handle存在,
用ZwQuerySystemInformation加SystemHandleInformation可以拿到整个系统所打开的handle,
然后判断handle的类型为file时则查询object的名字,即可获得整个系统内打开的文件以及文件夹。


这个. OK.
回复
Kudeet 2008-04-28
[Quote=引用 11 楼 shinefen 的回复:]
哎~我错了
有更简单的
哈哈~尝试更改文件夹名称~ 之后恢复

看能否更改成功
[/Quote]


那我要判断根目录下面的文件呢?你就去改盘符,并且改盘符也不一定有效.
回复
KeSummer 2008-04-28
有那么麻烦吗?
用ZwQuerySystemInformation就可以解决问题了。。可以用Process Explorer看到打开的文件。
回复
shinefen 2008-04-28
哎~我错了
有更简单的
哈哈~尝试更改文件夹名称~ 之后恢复

看能否更改成功
回复
Kudeet 2008-04-28
[Quote=引用 8 楼 linuxyf 的回复:]
楼上的兄台,这两个函数能采用一种类似于回调的机制监视文件夹下的文件是否被打开,不能主动检查一个文件夹下是否有文件被打开吧??
[/Quote]

是的,他是回调。你可以让你的监视程序随系统启动就开始监视,如果没有得到通知,当然就表示文件没有发生变化。

如果你只能在别人打开程序后再去判断文件是否打开的话,那就枚举吧,没辙!

以上所有的方法都只能实现普通的文件监视。实话告诉你,最彻底的方法只能是写文件过虑驱动,你可以去看FileMon的代码。
回复
linuxyf 2008-04-28
[Quote=引用 4 楼 jimoguilai 的回复:]
引用 3 楼 laiyiling 的回复:
Wwindows提供的API函数FindFirstChangeNotification和FindNextChangeNotification却可以实现这个功能。


mark
[/Quote]

楼上的兄台,这两个函数能采用一种类似于回调的机制监视文件夹下的文件是否被打开,不能主动检查一个文件夹下是否有文件被打开吧??
回复
linuxyf 2008-04-28
楼上的兄台,这两个函数能采用一种类似于回调的机制监视文件夹下的文件是否被打开,不能主动检查一个文件夹下是否有文件被打开吧??
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告
暂无公告