在delphi中如何判断一个文件正在被其它的程序或进程所调用?

来源:互联网 发布:天猫和淘宝有什么关系 编辑:程序博客网 时间:2024/04/30 00:46

function   isfileinuse(fname   :   string   )   :   boolean;    
  var    
      hfileres   :   hfile;    
  begin    
      result   :=   false;    
      if   not   fileexists(fname)   then    
          exit;    
      hfileres   :=   createfile(pchar(fname),   generic_read   or   generic_write,0,   nil,   open_existing,file_attribute_normal,   0);    
      result   :=   (hfileres   =   invalid_handle_value);    
      if   not   result   then    
          closehandle(hfileres);    
  end;    
 

发表者:whitetiger8

利用windows   api判断文件共享锁定状态  
   
  新疆塔里木农垦大学农业工程学院   陈立平      
  01-11-23   下午   01:59:05  
   
  --------------------------------------------------------------------------------  
     
   
  一、概述  
     
  锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据。要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定数据是否可读或可写,从而为开发出健壮的程序提供切实依据。    
  同样,在windows中,文件可以共享模式打开,它也涉及到锁的操作问题。根据windows中文件共享时加锁范围的大小,锁可分为全局锁和局部锁;全局锁以锁定文件全部内容为特征,而局部锁以锁定文件的局部内容为特征,且文件的锁定区域不可重复。根据windows中文件共享时锁的操作权限分类,锁可分为:读锁,写锁,读写锁。    
  利用上述文件中锁的区域不可重复的特性,我们可尝试给指定文件加一全局锁。若加锁成功,说明指定文件未被其它进程锁定;否则,说明有其它进程锁定了该文件。这里,我们利用两个windows   api文件操作函数:openfile和createfile来实现锁定状态的判断。    
     
  二、实现方法    
  1.   openfile函数使用说明    
  函数原型:function   openfile(const   lpfilename:   lpcstr;   var   lpreopenbuff:   tofstruct;      
  ustyle:   uint):   hfile;   stdcall;    
  函数功能:以不同方式打开文件的操作。建议    
  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    
    只写方式打开    
     
       
  返回值:成功,返回值为文件句柄;出错,返回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下文件锁定状态判断的问题。为避免发生共享冲突和提高文件操作程序的健壮性提供了很好的参考依据。    
     
  以上程序在windows98,delphi6下测试通过。 

原创粉丝点击