CreateFile()逻辑梳理(一)

        CreateFile()用来创建或打开一个文件,或打开一个I/O设备。CreateFile()可以操作的I/O设备有很多,比如文件流(File Stream)、物理磁盘、卷、控制台、磁带机、通信端口(比如COM口)、邮件槽、管道等。该函数最初是用来操作文件的,但随着系统功能的丰富,CreateFile()的功能也被扩充到可以操作大多数的设备。由于涉及的领域很广,CreateFile()的参数众多,逻辑复杂,本文尝试对其逻辑进行一下大致梳理,以便于读者更方便地调用该函数。

HANDLE CreateFile(
[in]    LPCSTR    lpFileName,
[in]    DWORD    dwDesiredAccess,
[in]    DWORD    dwShareMode,
[in,optional]    LPSECURITY_ATTRIBUTES    lpSecurityAttributes,
[in]    DWORD    dwCreationDisposition,
[in]    DWORD    dwFlagsAndSttributes,
[in,optional]    HANDLE    hTemplateFile
);

        CraeteFile()返回一个可用于访问文件或I/O设备地句柄,具体可以进行哪些操作取决于输入参数中指定的数值。如果该函数运行失败,会返回INVALIDE_HANDLE_VALUE,具体错误信息可调用GetLastError()获取。下面解释一下各参数。

        lpFileName用来指定期望操作的文件或设备的名称。对于文件,名称的长度受限于MAX_PATH常量,但在名称前面加上“\\?\”前缀可将长度扩大到32767个宽字符的长度。对于物理磁盘,需采用“\\.\PhysicalDriveX”的形式,X是从0开始的编号,比如“\\.\PhysicalDrive0”表示第一个磁盘。对于更换设备(Changer Device),其名称采用“\\.\ChangerX”的形式,X也是起始于0的编号。如果要打开卷或可移动存储(比如软盘或U盘),应采用”\\.\X:“的形式,X是以字母表示的盘符,比如”\\.\A:“表示A盘;如果最后面再跟一个反斜线(\)表示该盘的根目录。对于磁带设备,用”\\.\TAPEX“,比如”\\.\TAPE0“表示第一个磁带机。对于通信端口,采用"COMX",X表示从0到9的序号,如果X大于9,就要用”\\.\COMX“这种形式,比如”\\.\COM10“。这种形式也可用于标号为0到9的端口。对于主控台,用”CONIN$“和”CONOUT$“分别表示输入和输出设备。对于管道,采用”\\.\pipe\pipename“的形式。

        dwDesiredAccess用来指定对文件或设备所期望的操作,可以是读(GENERIC_READ)、写(GENERIC_WRITE)、既读又写,或者为0。如果该参数设置为0,CreateFile()可以查询到文件或设备的属性信息而不用访问其中的数据。

        dwShareMode用来指定期望与其他调用者对文件或设备采用的共享模式。可以是共享读(FILE_SHARE_READ)、共享写(FILE_SHARE_WRITE)、删除(FILE_SHARE_DELETE)、前者都指定、或为0。比如调用者以共享读模式打开文件,说明在此之前可能已经有其他调用者以共享读模式打开了文件,同时后续调用者也可以用共享读模式打开该文件。如果调用者指定了FILE_SHARE_DELETE,表示也允许后续调用者采用该共享模式打开文件,并对文件执行删除或重命名操作。

        如果dwShareMode被设置为0,表示不进行任何形式的共享,只要CreateFile()调用成功,那么在返回的句柄关闭之前,将不允许后续调用者以任何形式打开该文件或设备。

        dwCreationDispositon指对所指定文件或设备是否已经存在所做的处理规定,囊括了以下几种场景:

创建文件/设备
CREATE_NEW

如果指定文件不存在,且对指定的文件路径有写权限,则创建该文件。

如果指定文件已存在,函数失败,GetLastError()会返回ERROR_FILE_EXISTS(80)。

CREATE_ALWAYS

指定文件已存在,但将其清空为一个新文件。这时函数成功返回但会设置last-error为ERROR_ALREADY_EXISTS(183)。

如果指定文件不存在,且对指定的文件路径有写权限,则会创建一个新文件,函数成功返回。

打开文件/设备
OPEN_EXISTING

如果指定的文件或设备不存在,函数失败且last-error被设置为ERROR_FILE_NOT_FOUND(2)。

对于打开设备的调用,通常都是指定该值。

TRUNCATE_EXISTING

打开现有文件但将其截为空文件。调用者必须在dwDesiredAccess中设置GENERIC_WRITE。

如果指定的文件或设备不存在,函数失败且last-error被设置为ERROR_FILE_NOT_FOUND(2)。

OPEN_ALWAYS

即使指定文件不存在也要创建该文件。

如果指定文件已存在,函数成功返回但会设置last-error为ERROR_ALREADY_EXISTS(183)。

如果指定文件不存在,函数会创建该文件且成功返回,不设置last-error。

        经过以上对lpFileName、dwDesiredAccess、dwShareMode、dwCreationDisposition参数的介绍,基本上说明了CreateFile()的主体语义,即通过lpFileName、dwDesiredAccess用来说明希望对指定文件所进行的操作,同时再考虑文件或设备当前是否存在以及是否已被别人打开,将其体现到dwCreationDispositon和dwShareMode中。做好这些基本决定后,剩下的dwFlagsAndAttributes、lpSecurityAttributes和hTemplateFile就是与细节相关的设置了。

        需要特别注意的是,当打开一个已经被打开的文件或设备时,要确保dwShareMode与前面调用者指定的值兼容,同时dwDesiredAccess也不能与其冲突。
 

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值