如何判断一个文本文件是否已经被打开?(100分)

  • 主题发起人 主题发起人 ZeroMan
  • 开始时间 开始时间
Z

ZeroMan

Unregistered / Unconfirmed
GUEST, unregistred user!
具体说:<br>&nbsp; &nbsp; 现在的程序需要实现这样的功能:把一个内容随即增加的文本文件动态的复制到另一个文件夹里。<br>&nbsp; &nbsp; 目前程序的思路是:每隔一段时间就读取一次源文件,发现有了新的内容,就把新内容增添到备份文件中。<br>&nbsp; &nbsp; 问题:每次读取文件之前,先判断该文本是否有另一个程序正在往里面写东西,如果正在被其它程序操作,则先不读取该文本,等下次循环回来,再判断,直到判断出文件没有被任何程序操作,才读取源文件,进行相应操作。<br>&nbsp; &nbsp; 目前需要一个函数实现如下功能:<br>&nbsp; &nbsp; 给定一个 String 参数,指定文本文件的完整路径。<br>&nbsp; &nbsp; 返回一个Boolean值,说明文件是否正被操作。<br>&nbsp; &nbsp;
 
<br>应该判断不了文件是否被其它编辑器编辑。<br><br>
 
别人的东西,呵呵,你看看吧。<br><br>利用Windows API判断文件共享锁定状态 <br><br>新疆塔里木农垦大学农业工程学院 陈立平 &nbsp;<br>一、概述<br><br>锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据。要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定数据是否可读或可写,从而为开发出健壮的程序提供切实依据。 <br>同样,在Windows中,文件可以共享模式打开,它也涉及到锁的操作问题。根据Windows中文件共享时加锁范围的大小,锁可分为全局锁和局部锁;全局锁以锁定文件全部内容为特征,而局部锁以锁定文件的局部内容为特征,且文件的锁定区域不可重复。根据Windows中文件共享时锁的操作权限分类,锁可分为:读锁,写锁,读写锁(可读可写,全局锁)。 <br>利用上述文件中锁的区域不可重复的特性,我们可尝试给指定文件加一全局锁。若加锁成功,说明指定文件未被其它进程锁定;否则,说明有其它进程锁定了该文件。这里,我们利用两个Windows Api文件操作函数:OpenFile和CreateFile来实现锁定状态的判断。 <br><br>二、实现方法 <br>1. OpenFile函数使用说明 <br>函数原型:function OpenFile(const lpFileName: LPCSTR; var lpReOpenBuff: TOFStruct; &nbsp;<br>uStyle: UINT): HFILE; stdcall; <br>函数功能:以不同方式打开文件的操作(为兼容16位Windows程序保留的函数)。建议 <br>Windows下使用CreateFile函数。 <br>参数说明:lpFileName: 要打开文件的名称 <br>lpReOpenBuff: 变量指针,用于存储文件被首次打开时接收信息。 <br>UStyle: 打开文件的常量类型。 <br>常量名 <br>意义 <br><br>Of_Create <br>创建文件 <br><br>Of_Delete <br>删除指定文件 <br><br>Of_Exist <br>打开文件以验证其存在否?存在,返回一无效句柄;否则,返回负数 <br><br>Of_Parse <br>填充lpReOpenBuff内容,但不进行任何操作 <br><br>Of_Prompt <br>如存在不存在,则显示一有重试和取消按钮的消息框 <br><br>Of_Read <br>只读方式打开 <br><br>Of_ReadWrite <br>读写方式打开 <br><br>Of_ReOpen <br>打开lpReOpenBuff内指定的文件,而不依据lpFileName <br><br>Of_Search <br>强迫Windows查找文件---即使指定了文件路径 <br><br>Of_Share_Compat <br>文件可由多个程序多次打开 <br><br>Of_Share_Deny_None <br>共享打开 <br><br>Of_Share_Deny_Read <br>禁止其它程序读该文件 <br><br>Of_Share_Deny_Write <br>禁止其它程序写该文件 <br><br>Of_Share_Exclusive <br>独占方式打开文件,其它程序不得再打开该文件 <br><br>Of_Write <br>只写方式打开 <br><br>  <br>返回值:成功,返回值为文件句柄(但可能无效,如:Of_Exist);出错,返回HFile_Error。 <br>2. CreateFile函数使用说明 <br>函数原型:function CreateFile(lpFileName: PChar; &nbsp;<br>dwDesiredAccess, dwShareMode: DWORD; <br>lpSecurityAttributes: PSecurityAttributes; &nbsp;<br>dwCreationDisposition, dwFlagsAndAttributes: DWORD; <br>hTemplateFile: THandle): THandle; stdcall; <br>函数功能:以不同方式打开文件的操作,还可操作管道、邮槽、通信服务、设备以及控 <br>制台等。 <br>参数说明: lpFileName: 要打开文件的名称 <br>dwDesiredAccess:期望存取模式 <br>取值 0:只允许获取一个设备的相关信息。 <br>Generic_Read:只允许读设备 <br>Generic_Write:只允许写设备(二者可组合使用)。 <br>dwShareMode:共享模式。 <br>取值 0: 不共享。 <br>File_Share_Read和/或File_Share_Write:共享读和/或写。 <br>lpSecurityAttributes: 定义文件安全特性的指针(前提:操作系统支持)。 <br>DwCreationDisposition: 打开和创建文件方式。 <br>取值 Create_New: 总创建新文件,如文件已存在,则出错。 <br>Create_Always: 总创建新文件(会覆盖旧文件)。 <br>Open_Existing: 打开已存在的文件,若文件不存在,则出错。 <br>Open_Always: 总打开文件,如不存在,则创建。 <br>dwFlagsAndAttributes: 要打开文件的标志和属性(如:隐藏,系统等)。 <br>一般用File_Attribute_Normal,默认属性。 <br>hTemplateFile::模板文件句柄。 <br>若非0则指定一个文件句柄;否则,新文件将从这个文件复制 <br>扩展属性。 <br>返回值:成功,返回值为文件句柄;出错,返回Invalid_Handle_Value。 <br><br>3。程序实现 <br>利用上述两个函数,我们可编写程序判断某文件是否正在被其它进程锁定,以下为详细代码。 <br>//利用OpenFile Api函数判断 <br>function FileLocked(Fn: string): Boolean; <br>var <br>I : Integer; <br>Struct: TOfStruct; <br>Style: Cardinal; <br>Hdl: Hfile; <br>Drive: String; <br>begin <br>Style := OF_Share_Exclusive; //排它方式打开 <br>Drive := UpperCase(Fn[1]); <br>Struct.fFixedDisk := Ord(Drive &lt;&gt; 'A'); //判断是否是硬盘 <br>Struct.cBytes := SizeOf(Struct); <br>For I := 1 to Length(Fn) do <br>Struct.szPathName[I-1] := Fn; &nbsp;<br>Struct.szPathName := Chr(0); //填充文件名 <br>Hdl := OpenFile(Pchar(Fn), Struct, Style); <br>if Hdl = HFILE_ERROR then <br>begin <br>Result := True; //文件被锁定 <br>Showmessage(SysErrorMessage(GetLastError)); //显示错误原因 <br>end <br>else <br>Result := False; <br>end; <br><br>//利用CreateFile Api函数判断 <br>function LockedFile(Fn: string): Boolean; <br>var <br>AFile: THandle; <br>SecAtrrs: TSecurityAttributes; <br>begin <br>FillChar(SecAtrrs, SizeOf(SecAtrrs), #0); <br>SecAtrrs.nLength := SizeOf(SecAtrrs); //结构体长度 <br>SecAtrrs.lpSecurityDescriptor := nil; //安全描述 <br>SecAtrrs.bInheritHandle := True; //继承标志 <br>AFile := CreateFile(PChar(Fn), GENERIC_READ or GENERIC_WRITE, <br>FILE_SHARE_Read, @SecAtrrs, OPEN_EXISTING, <br>FILE_ATTRIBUTE_Normal, 0); <br>if AFile = INVALID_HANDLE_VALUE then <br>begin <br>Result := True; //文件被锁定 <br>showmessage(SysErrorMessage(GetLastError)); <br>end <br>else <br>Result := False; <br>end; <br><br>4。程序的测试 <br>在Delphi中新建一Application,在Form1的OnCreate事件中写入: <br>if Not FileLocked(‘c:/windows/desktop/a.txt’) then Showmessage(‘Cannot Open 1’); <br>或 <br>if Not LockedFile (‘c:/windows/desktop/a.txt’) then Showmessage(‘Cannot Open 2’); <br>再新建一批处理文件保存到桌面上,内容为: <br>dir c:/*.*/s&gt;c:/windows/desktop/a.txt’ <br>运行此批处理文件,然后运行上述Delphi程序。这时候会出现消息框“其他进程正使用该文件, 因此现在无法访问。”。当批处理命令运行完毕后,再运行此程序则不会出现此信息。此时,再双击a.txt文档,记事本程序将无法打开该文档,说明加锁成功。 <br><br>三、结束语 <br>以上用两种方法实现了如何判断一个文件是否正被其它进程锁定。其中,方法一实现较为简单,但兼容性不好;而方法二为Windows推荐的方法,且功能强大。 <br>利用以上实现方法,较好地解决了Windows下文件锁定状态判断的问题。为避免发生共享冲突和提高文件操作程序的健壮性提供了很好的参考依据。 <br><br>以上程序在Windows98,Delphi6下测试通过。
 
<br>楼上的,如果不锁定怎办?例如用记事本打开一个文本文件。<br>
 
如果其它程序不是以独占方式打开是无法判定的。<br>function E9FileStatus(Const Origin: string): boolean; <br>var<br>F: TFileStream; <br>begin <br>{<br>值 含义<br>fmCreate 根据所给名字创建文件。如果所给名字的文件存在,以写状态打开文件。<br>fmOpenRead 以只读状态打开文件<br>fmOpenWrite 以只写状态打开文件。文件全部重写,替代已有内容。<br>fmOpenReadWrite 打开文件,修改而不是替换文件内容。<br>共享(share)状态必须是以下值之一:<br>值 意义<br>fmShareCompat 共享与文件控制块(FCB)的打开方式兼容。<br>fmShareExclusive 其他程序不能以任何理由打开文件。<br>fmShareDenyWrite 其他程序能以只读方式打开文件,但不能写。<br>fmShareDenyRead 其他程序能以只写方式打开文件,但不能读。<br>fmShareDenyNone 不禁止其他程序读或写文件。<br>如果文件不能被打开, Create 将产生异常。<br>如果文件未被锁定,将返回true<br>}<br>try<br>try<br>F := TFileStream.Create(Origin, fmOpenReadWrite OR fmShareExclusive);<br>Result := true;<br>finally<br>F.Free;<br>end;<br>except<br>Result := false;<br>end; <br>end;
 
用独占的方式打开,如果失败。。。
 
H := FileOpen('Filename',fmOpenWrite);<br>if H&lt;=0 then<br>&nbsp; &nbsp;//打开失败,文件已经被打开过<br>else<br>&nbsp; //文件还没有被打开过
 
多人接受答案了。
 
后退
顶部