一、概述 
锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据。要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定数据是否可读或可写,从而为开发出健壮的程序提供切实依据。   
同样,在Windows中,文件可以共享模式打开,它也涉及到锁的操作问题。根据Windows中文件共享时加锁范围的大小,锁可分为全局锁和局部锁;全局锁以锁定文件全部内容为特征,而局部锁以锁定文件的局部内容为特征,且文件的锁定区域不可重复。根据Windows中文件共享时锁的操作权限分类,锁可分为:读锁,写锁,读写锁(可读可写,全局锁)。

利用上述文件中锁的区域不可重复的特性,我们可尝试给指定文件加一全局锁。若加锁成功,说明指定文件未被其它进程锁定;否则,说明有其它进程锁定了该文件。这里,我们利用两个Windows   Api文件操作函数:OpenFile和CreateFile来实现锁定状态的判断。

二、实现方法

1.   OpenFile函数使用说明   
函数原型:function   OpenFile(const   lpFileName:   LPCSTR;   var   lpReOpenBuff:   TOFStruct;   
uStyle:   UINT):   HFILE;   stdcall;   
函数功能:以不同方式打开文件的操作(为兼容16位Windows程序保留的函数)。建议   
Windows下使用CreateFile函数。   
参数说明:lpFileName:   要打开文件的名称   
lpReOpenBuff:   变量指针,用于存储文件被首次打开时接收信息。   
UStyle:   打开文件的常量类型。   
常量名   
意义

Of_Create   
创建文件

Of_Delete   
删除指定文件

Of_Exist   
打开文件以验证其存在否?存在,返回一无效句柄;否则,返回负数

Of_Parse   
填充lpReOpenBuff内容,但不进行任何操作

Of_Prompt   
如存在不存在,则显示一有重试和取消按钮的消息框

Of_Read   
只读方式打开

Of_ReadWrite   
读写方式打开

Of_ReOpen   
打开lpReOpenBuff内指定的文件,而不依据lpFileName

Of_Search   
强迫Windows查找文件---即使指定了文件路径

Of_Share_Compat   
文件可由多个程序多次打开

Of_Share_Deny_None   
共享打开

Of_Share_Deny_Read   
禁止其它程序读该文件

Of_Share_Deny_Write   
禁止其它程序写该文件

Of_Share_Exclusive   
独占方式打开文件,其它程序不得再打开该文件

Of_Write   
只写方式打开

返回值:成功,返回值为文件句柄(但可能无效,如:Of_Exist);出错,返回HFile_Error。   
2.   CreateFile函数使用说明   
函数原型:function   CreateFile(lpFileName:   PChar;   
dwDesiredAccess,   dwShareMode:   DWORD;   
lpSecurityAttributes:   PSecurityAttributes;   
dwCreationDisposition,   dwFlagsAndAttributes:   DWORD;   
hTemplateFile:   THandle):   THandle;   stdcall;   
函数功能:以不同方式打开文件的操作,还可操作管道、邮槽、通信服务、设备以及控   
制台等。   
参数说明:   lpFileName:   要打开文件的名称   
dwDesiredAccess:期望存取模式   
取值   0:只允许获取一个设备的相关信息。   
Generic_Read:只允许读设备   
Generic_Write:只允许写设备(二者可组合使用)。   
dwShareMode:共享模式。   
取值   0:   不共享。   
File_Share_Read和/或File_Share_Write:共享读和/或写。   
lpSecurityAttributes:   定义文件安全特性的指针(前提:操作系统支持)。   
DwCreationDisposition:   打开和创建文件方式。   
取值   Create_New:   总创建新文件,如文件已存在,则出错。   
Create_Always:   总创建新文件(会覆盖旧文件)。   
Open_Existing:   打开已存在的文件,若文件不存在,则出错。   
Open_Always:   总打开文件,如不存在,则创建。   
dwFlagsAndAttributes:   要打开文件的标志和属性(如:隐藏,系统等)。   
一般用File_Attribute_Normal,默认属性。   
hTemplateFile::模板文件句柄。   
若非0则指定一个文件句柄;否则,新文件将从这个文件复制   
扩展属性。   
返回值:成功,返回值为文件句柄;出错,返回Invalid_Handle_Value。

3。程序实现   
利用上述两个函数,我们可编写程序判断某文件是否正在被其它进程锁定,以下为详细代码。   
//利用OpenFile   Api函数判断   
function   FileLocked(Fn:   string):   Boolean;   
var   
I   :   Integer;   
Struct:   TOfStruct;   
Style:   Cardinal;   
Hdl:   Hfile;   
Drive:   String;   
begin   
Style   :=   OF_Share_Exclusive;   //排它方式打开   
Drive   :=   UpperCase(Fn[1]);   
Struct.fFixedDisk   :=   Ord(Drive   <>   ’A’);   //判断是否是硬盘   
Struct.cBytes   :=   SizeOf(Struct);   
For   I   :=   1   to   Length(Fn)   do   
Struct.szPathName[I-1]   :=   Fn[I];   
Struct.szPathName[I]   :=   Chr(0);   //填充文件名   
Hdl   :=   OpenFile(Pchar(Fn),   Struct,   Style);   
if   Hdl   =   HFILE_ERROR   then   
begin   
Result   :=   True;   //文件被锁定   
Showmessage(SysErrorMessage(GetLastError));   //显示错误原因   
end   
else   
Result   :=   False;   
end;

//利用CreateFile   Api函数判断   
function   LockedFile(Fn:   string):   Boolean;   
var   
AFile:   THandle;   
SecAtrrs:   TSecurityAttributes;   
begin   
FillChar(SecAtrrs,   SizeOf(SecAtrrs),   #0);   
SecAtrrs.nLength   :=   SizeOf(SecAtrrs);   //结构体长度   
SecAtrrs.lpSecurityDescriptor   :=   nil;   //安全描述   
SecAtrrs.bInheritHandle   :=   True;   //继承标志   
AFile   :=   CreateFile(PChar(Fn),   GENERIC_READ   or   GENERIC_WRITE,   
FILE_SHARE_Read,   @SecAtrrs,   OPEN_EXISTING,   
FILE_ATTRIBUTE_Normal,   0);   
if   AFile   =   INVALID_HANDLE_VALUE   then   
begin   
Result   :=   True;   //文件被锁定   
showmessage(SysErrorMessage(GetLastError));   
end   
else   
Result   :=   False;   
end;

4。程序的测试   
在Delphi中新建一Application,在Form1的OnCreate事件中写入:   
if   Not   FileLocked(‘c:\windows\desktop\a.txt’)   then   Showmessage(‘Cannot   Open   1’);   
或   
if   Not   LockedFile   (‘c:\windows\desktop\a.txt’)   then   Showmessage(‘Cannot   Open   2’);   
再新建一批处理文件保存到桌面上,内容为:   
dir   c:\*.*/s> c:\windows\desktop\a.txt’   
运行此批处理文件,然后运行上述Delphi程序。这时候会出现消息框“其他进程正使用该文件,   因此现在无法访问。”。当批处理命令运行完毕后,再运行此程序则不会出现此信息。此时,再双击a.txt文档,记事本程序将无法打开该文档,说明加锁成功。

三、结束语   
以上用两种方法实现了如何判断一个文件是否正被其它进程锁定。其中,方法一实现较为简单,但兼容性不好;而方法二为Windows推荐的方法,且功能强大。   
利用以上实现方法,较好地解决了Windows下文件锁定状态判断的问题。为避免发生共享冲突和提高文件操作程序的健壮性提供了很好的参考依据。

http://blog.csdn.net/yanjiaye520/article/details/7880967

Delphi Windows API判断文件共享锁定状态(使用OpenFile来判断)的更多相关文章

  1. Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)

    一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...

  2. c# 判断窗体是否永在最前(TopMost),调用windows API

    许多程序都可以把自身的窗体设为最前显示状态,这个可以参考博客c#让窗体永在最前 调用windows api 将窗体设为topmost.那么如何判断桌面上的一个窗体是否为最前显示状态呢,不光是自己的程序 ...

  3. 浅议Delphi中的Windows API调用(举的两个例子分别是String和API,都不错,挺具有代表性)

    浅议Delphi中的Windows API调用http://tech.163.com/school • 2005-08-15 10:57:41 • 来源: 天极网为了能在Windows下快速开发应用程 ...

  4. Delphi - Windows系统下,Delphi调用API函数和7z.dll动态库,自动把文件压缩成.tar.gz格式的文件

    项目背景 应欧美客户需求,需要将文件压缩成.tar.gz格式的文件,并上传给客户端SFTP服务器. 你懂的,7-Zip软件的显著特点是文件越大压缩比越高,在Linux系统上相当于我们Windows系统 ...

  5. Delphi 常用API 函数

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小 AnyPopup 判断屏幕上是否存在任何弹出式窗口 ArrangeIconic ...

  6. Delphi 常用API 函数列表

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小AnyPopup 判断屏幕上是否存在任何弹出式窗口ArrangeIconicWi ...

  7. Windows API 函数列表 附帮助手册

    所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...

  8. DELPHI下API简述(1800个API)

    DELPHI下API简述 http://zero.cnbct.org/show.asp?id=144 auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属 ...

  9. Windows API Finishing

    input { font-size: 14px; height: 26px } td { border-style: none; border-color: inherit; border-width ...

随机推荐

  1. MinGW是什么

    MinGW是什么? MinGW是建立在gcc和binutils项目上的,用来编译和连接代码,使之运行在windows系统上: 提供c.c++和fortran编译器和相关工具: MinGW=Minima ...

  2. 设计模式(Abstract Factory)抽象工厂

    1. 需求: 设计一个电脑组装程序,对于组装品牌电脑. 用零件组装(主板.硬盘.显示器)由品牌提供的所有. 让我们组装一台联想电脑,板子.由联想提供. (眼下仅仅有Lenovo和Dell两种品牌) 2 ...

  3. Ubuntu14.04更新源

    Ubuntu14.04更新源 http://jingyan.baidu.com/article/7f41ecec1b7a2e593d095ce6.html Ubuntu源 http://wiki.ub ...

  4. WM_PAINT在微软官方定义中,wParam和lParam都没有使用,所以就被Delphi给重定义了这个消息,还增加了DC(Delphi可任意改写消息的结构)

    LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); Parameters wParam ...

  5. Troubleshooting(updating...)

    记录了工作和学习中一些杂碎的问题. 问题:RDP一直处于连接状态,除非重启 描述:表面看上去是应该在一定时间还连接不上,就让它断开.深层问题是,初次连接一个新的IP地址,Win7以上的系统,会有个CA ...

  6. chrome你这是入侵OSX了么?

    今天突然发现安装chrome的应用后,会在Dock中出现如下图标,点击即可启动chrome相关应用,很是方便.

  7. Java面试题精选(一)基础概念和面向对象

    --   基础概念和面向对象   --      全程将为大家剖析几大部分内容,由于学习经验有限,望大家谅解并接受宝贵的意见: 基础概念部分     ★★   : 常出现的高频率单词的区别理解(异常. ...

  8. [转载]关于网传JDK1.7语法层次支持集合的问题

    以  JDK1.7新特性 为关键词进行百度的话,总能发现这样的描述,说: 从语法层面上支持集合,不再是数组的专利.还有这样的例子: final List<Integer> piDigits ...

  9. php使用 _before_index() 来实现访问页面前,判断登录

    C:\wamp\www\DEVOPS\Home\Lib\Action: <?php class IndexAction extends Action { function index(){ $t ...

  10. HTML语言简单回顾

    简单复习一下html语言. html的基本结构如下: <html> <head> <title></title> </head> <b ...