• delphi文件的操作,利用Windows API判断文件共享锁定状态


    利用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;
    函数功能:以不同方式打开文件的操作(为兼容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:windowsdesktopa.txt’) then Showmessage(‘Cannot Open 1’);

    if Not LockedFile (‘c:windowsdesktopa.txt’) then Showmessage(‘Cannot Open 2’);
    再新建一批处理文件保存到桌面上,内容为:
    dir c:*.*/s>c:windowsdesktopa.txt’
    运行此批处理文件,然后运行上述Delphi程序。这时候会出现消息框“其他进程正使用该文件, 因此现在无

  • 相关阅读:
    -/bin/sh: ./led: not found的解决办法
    s5pv210启动debian出错提示bash: cannot set terminal process group (-1): Inappropriate ioctl for device
    s5pv210 cpu运行debian
    解决qt程序运行时的cannot create Qt for Embedded Linux data directory: /tmp/qtembedded-0出错情形
    easyui datagrid的API
    <% 拼写页面
    easyui编辑editor
    H2数据库介绍
    easyUI的datagrid控件日期列格式化
    oracle取出所有表和视图
  • 原文地址:https://www.cnblogs.com/yclizq/p/12185018.html
Copyright © 2020-2023  润新知