CreateFile3 函数 (fileapi.h)

创建或打开文件或 I/O 设备。 最常用的 I/O 设备如下所示:文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道。 该函数返回一个句柄,该句柄可用于访问各种类型的 I/O 的文件或设备,具体取决于文件或设备以及指定的标志和属性。

从沙盒打包的应用调用时, CreateFile3 将简化。 只能打开 ApplicationData.LocalFolderPackage.InstalledLocation 目录中的文件或目录。 无法打开命名管道或 mailslot 或创建加密文件(FILE_ATTRIBUTE_ENCRYPTED)。

注释

 此处介绍应用的本地文件夹和包的安装位置,而不是包图中的其他包,如资源包。 CreateFile3 不支持在包图中的其他包中打开文件。 若要将此作作为事务处理作执行,这会导致可用于事务处理 I/O 的句柄,请使用 CreateFileTransacted 函数。

语法

HANDLE CreateFile3(
  LPCWSTR                           lpFileName,
  DWORD                             dwDesiredAccess,
  DWORD                             dwShareMode,
  DWORD                             dwCreationDisposition,
  LPCREATEFILE3_EXTENDED_PARAMETERS pCreateExParams
);

参数

lpFileName

要创建或打开的文件或设备的名称。

有关特殊设备名称的信息,请参阅 定义 MS-DOS 设备名称

若要创建文件流,请指定文件的名称、冒号,然后指定流的名称。 有关详细信息,请参阅 文件流

小提示

 你可以选择加入以删除 MAX_PATH限制, 而无需追加“\?”。 有关详细信息,请参阅 命名文件、路径和命名空间 的“最大路径长度限制”部分。

dwDesiredAccess

请求对文件或设备的访问权限,可以汇总为读取、写入或两者均不为零。

最常用的值是 GENERIC_READGENERIC_WRITE或两者(GENERIC_READ | GENERIC_WRITE)。 有关详细信息,请参阅 通用访问权限文件安全性和访问权限文件访问权限常量ACCESS_MASK

如果此参数为零,则应用程序可以在不访问该文件或设备的情况下查询某些元数据(如文件、目录或设备属性),即使 拒绝GENERIC_READ 访问也是如此。

不能请求与已打开句柄的打开请求中 dwShareMode 参数指定的共享模式冲突的访问模式。

有关详细信息,请参阅本主题的 “备注 ”部分和 “创建和打开文件”。

dwShareMode

请求的文件或设备的共享模式,可以读取、写入、删除、所有这些或无(请参阅下表)。 对属性或扩展属性的访问请求不受此标志的影响。

如果此参数为零且 CreateFile3 成功,则文件或设备无法共享,并且无法在文件或设备的句柄关闭之前再次打开。 有关详细信息,请参阅备注部分。

无法请求与具有打开句柄的现有请求中指定的访问模式冲突的共享模式。 CreateFile3 将失败, GetLastError 函数将返回 ERROR_SHARING_VIOLATION

若要使进程能够在另一个进程打开文件或设备时共享文件或设备,请使用以下一个或多个值的兼容组合。 有关此参数与 dwDesiredAccess 参数的有效组合的详细信息,请参阅 “创建和打开文件”。

注释

 无论进程上下文如何,每个打开句柄的共享选项都将有效,直到关闭该句柄。

价值 含义
0
0x00000000
如果其他进程请求删除、读取或写入访问权限,则阻止其他进程打开文件或设备。 仅当应用程序对文件具有写入访问权限时,才授予对文件或目录的独占访问权限。
FILE_SHARE_DELETE
0x00000004
启用对文件或设备上的后续打开作以请求删除访问权限。 否则,如果进程请求删除访问权限,则无法打开文件或设备。 如果未指定此标志,但文件或设备已打开以删除访问权限,则函数将失败。

注意: 删除访问权限允许删除和重命名作。
FILE_SHARE_READ
0x00000001
允许对文件或设备执行后续打开作以请求读取访问权限。 否则,如果进程请求读取访问权限,则其他进程无法打开文件或设备。 如果未指定此标志,但已打开文件或设备进行读取访问,则函数将失败。 如果打开文件或目录,并且未指定此标志,并且调用方没有对文件或目录的写入访问权限,则函数将失败。
FILE_SHARE_WRITE
0x00000002
允许对文件或设备执行后续打开作以请求写入访问权限。 否则,如果进程请求写入访问权限,则其他进程无法打开文件或设备。 如果未指定此标志,但已打开文件或设备进行写入访问或具有写入访问权限的文件映射,则函数将失败。

dwCreationDisposition

对存在或不存在的文件或设备执行的作。

对于文件以外的设备,此参数通常设置为 OPEN_EXISTING

有关详细信息,请参阅备注部分。

此参数必须是以下值之一,不能组合这些值:

价值 含义
CREATE_ALWAYS
2
始终创建新文件。 如果指定的文件存在且可写,则函数将截断文件、函数成功,最后错误代码设置为 ERROR_ALREADY_EXISTS (183)。 如果指定的文件不存在且路径有效,则会创建一个新文件,该函数会成功,最后一个错误代码设置为零。 有关详细信息,请参阅本主题的 “备注 ”部分。
CREATE_NEW
1
仅当该文件尚不存在时,才会创建一个新文件。 如果指定的文件存在,函数将失败,最后一个错误代码设置为 ERROR_FILE_EXISTS (80)。 如果指定的文件不存在,并且是可写位置的有效路径,则会创建一个新文件。
OPEN_ALWAYS
4
始终打开文件。 如果指定文件存在,则函数成功,最后一个错误代码设置为 ERROR_ALREADY_EXISTS (183)。 如果指定的文件不存在并且是可写位置的有效路径,该函数将创建一个文件,最后一个错误代码设置为零。
OPEN_EXISTING
3
仅当文件或设备存在时才打开该文件或设备。 如果指定的文件或设备不存在,函数将失败,最后一个错误代码设置为 ERROR_FILE_NOT_FOUND (2)。 有关设备的详细信息,请参阅“ 备注 ”部分。
TRUNCATE_EXISTING
5
打开一个文件并截断它,使其大小为零字节,仅当它存在时。 如果指定的文件不存在,函数将失败,最后一个错误代码设置为 ERROR_FILE_NOT_FOUND (2)。 调用过程必须打开文件,并将 GENERIC_WRITE 位设置为 dwDesiredAccess 参数的一部分。

pCreateExParams

指向可选 CREATEFILE3_EXTENDED_PARAMETERS 结构的指针。

返回值

如果函数成功,则返回值是指定文件、设备、命名管道或邮件槽的打开句柄。

如果函数失败,则返回值 INVALID_HANDLE_VALUE。 若要获取扩展的错误信息,请调用 GetLastError。 可能的错误包括:

返回代码 说明
ERROR_PATH_REDIRECTED lpFileName 由重新分析点和/或符号链接重定向。

注解

CreateFile3 的行为方式与 CreateFile2 完全相同,但有一个例外:如果 lpFileName 通过重新分析点或符号链接重定向,则作将失败。 可以使用可添加到 dwFileFlags 的新标志禁用此行为。

若要编译使用 CreateFile3 函数的应用程序,请将 _WIN32_WINNT0x0602 定义为或更高版本。 有关详细信息,请参阅 使用 Windows 标头

CreateFile3 支持文件交互以及 Windows 开发人员可用的大多数其他类型的 I/O 设备和机制。 本部分尝试介绍开发人员在不同上下文和不同 I/O 类型中使用 CreateFile3 时可能会遇到的各种问题。 仅当专门引用存储在文件系统上实际文件中的数据时,文本才会尝试使用单词 文件 。 但是,某些文件用法可能更普遍地引用支持类似 文件的 机制的 I/O 对象。 由于前面提到的历史原因,术语 文件的 这种自由使用在常量名称和参数名称中尤其普遍。

使用 CreateFile3 返回的对象句柄完成应用程序后,请使用 CloseHandle 函数关闭句柄。 这不仅释放了系统资源,还可以对共享文件或设备以及将数据提交到磁盘等内容产生更广泛的影响。 本主题中会相应地说明具体内容。

某些文件系统(如 NTFS 文件系统)支持单个文件和目录的压缩或加密。 在具有具有此支持的装载文件系统的卷上,新文件继承其目录的压缩和加密属性。

不能使用 CreateFile3 控制文件或目录上的压缩、解压缩或解密。 有关详细信息,请参阅 创建和打开文件文件压缩和解压缩以及 文件加密

如果 pCreateExParams 参数NULL中传递的 CREATEFILE3_EXTENDED_PARAMETERS 结构的 lpSecurityAttributes 成员,则应用程序可能创建的任何子进程都无法继承 CreateFile3 返回的句柄。 有关此成员的以下信息也适用:

  • 如果 bInheritHandle 成员变量不是 FALSE任何非零值,则可以继承句柄。 因此,如果不希望句柄可继承,则必须正确初始化 FALSE 此结构成员。
  • 文件或目录的默认安全描述符中的访问控制列表 (ACL) 是从其父目录继承的。
  • 目标文件系统必须支持 lpSecurityDescriptor 成员对文件和目录的安全性,才能对其产生影响,这可以通过 使用 GetVolumeInformation 来确定。

在 Windows 8 和 Windows Server 2012 中,以下技术支持此函数:

科技 支持
服务器消息块 (SMB) 3.0 协议 是的
SMB 3.0 透明故障转移 (TFO)
具有横向扩展文件共享的 SMB 3.0 (SO)
群集共享卷文件系统 (CsvFS) 是的
可复原文件系统 (ReFS) 是的

如果对此函数的调用创建文件,则行为没有变化。 此外,请考虑有关 pCreateExParams 参数中传递的 CREATEFILE3_EXTENDED_PARAMETERS 结构的 dwFileFlags 成员的 FILE_FLAG_OPEN_REPARSE_POINT 标志的以下信息:

  • 如果指定 了FILE_FLAG_OPEN_REPARSE_POINT
    • 如果打开现有文件并且它是符号链接,则返回的句柄是符号链接的句柄。
    • 如果指定 了TRUNCATE_EXISTINGFILE_FLAG_DELETE_ON_CLOSE ,受影响的文件是符号链接。
  • 如果未指定 FILE_FLAG_OPEN_REPARSE_POINT
    • 如果打开现有文件并且它是符号链接,则返回的句柄是目标的句柄。
    • 如果指定了 CREATE_ALWAYSTRUNCATE_EXISTINGFILE_FLAG_DELETE_ON_CLOSE,受影响的文件就是目标。

文件

如果重命名或删除文件,然后在不久后还原该文件,系统会在缓存中搜索要还原的文件信息。 缓存信息包括其短/长名称对和创建时间。

如果在之前调用 DeleteFileDeleteFile2 后挂起删除的文件上调用 CreateFile3,该函数将失败。 作系统会延迟文件删除,直到文件的所有句柄都关闭。 GetLastError 返回 ERROR_ACCESS_DENIED

dwDesiredAccess 参数可以是零,允许应用程序在没有访问文件的情况下查询文件属性(如果应用程序正在运行且具有足够安全设置)。 这可用于测试文件是否存在,而无需打开该文件进行读取和/或写入访问,或获取有关文件或目录的其他统计信息。 请参阅 “获取和设置文件信息”和GetFileInformationByHandle

当应用程序跨网络创建文件时,最好用于 GENERIC_READ | GENERIC_WRITEdwDesiredAccess ,而不是单独使用 GENERIC_WRITE 。 生成的代码速度更快,因为重定向程序可以使用缓存管理器,并发送更少的 SMB 和更多数据。 这种组合还避免了跨网络写入文件偶尔会返回 ERROR_ACCESS_DENIED的问题。

有关详细信息,请参阅 创建和打开文件

文件流

在 NTFS 文件系统上,可以使用 CreateFile3 在文件中创建单独的流。 有关详细信息,请参阅 文件流

目录

应用程序无法使用 CreateFile3 创建目录,因此,对于此用例,只有 OPEN_EXISTING 值对 dwCreationDisposition 有效。 若要创建目录,应用程序必须调用 CreateDirectoryCreateDirectoryEx 或 CreateDirectory2

若要使用 CreateFile3 打开目录,请将FILE_FLAG_BACKUP_SEMANTICS标志指定为 pCreateExParams 参数中传递的 CREATEFILE3_EXTENDED_PARAMETERS 结构的 dwFileFlags 成员的一部分。 在没有 SE_BACKUP_NAMESE_RESTORE_NAME 特权的情况下使用此标志时,仍适用适当的安全检查。

在使用 CreateFile3 对 FAT 或 FAT32 文件系统卷进行碎片整理期间打开目录时,请不要指定 MAXIMUM_ALLOWED 访问权限。 如果这样做,则拒绝对目录的访问。 请改为指定 GENERIC_READ 访问权限。

有关详细信息,请参阅 “关于目录管理”。

物理磁盘和卷

对磁盘或卷的直接访问受到限制。

可以使用 CreateFile3 函数打开物理磁盘驱动器或卷,该驱动器返回可与 DeviceIoControl 函数一起使用的直接访问存储设备 (DASD) 句柄。 这样,便可以直接访问磁盘或卷,例如分区表等磁盘元数据。 但是,这种类型的访问还会向潜在的数据丢失公开磁盘驱动器或卷,因为使用此机制对磁盘进行不正确的写入可能会使其内容无法访问作系统。 若要确保数据完整性,请务必熟悉 DeviceIoControl ,以及其他 API 的行为方式与直接访问句柄不同,而不是文件系统句柄。

必须满足以下要求才能成功进行此类调用:

  • 调用方必须具有管理权限。 有关详细信息,请参阅 使用特殊特权运行。
  • dwCreationDisposition 参数必须具有OPEN_EXISTING标志。
  • 打开卷或软盘时, dwShareMode 参数必须具有 FILE_SHARE_WRITE 标志。

注释

  dwDesiredAccess 参数可以是零,允许应用程序在不访问设备的情况下查询设备属性。 这适用于应用程序来确定软盘驱动器的大小及其支持的格式,而无需驱动器中的软盘,例如。 它还可用于读取统计信息,而无需更高级别的数据读取/写入权限。

打开物理驱动器 x:时, lpFileName 字符串应采用以下格式:“\.\PhysicalDriveX”。

硬盘编号从零开始。 下表显示了物理驱动器字符串的一些示例。

字符串 含义
“\.\PhysicalDrive0” 打开第一个物理驱动器。
“\.\PhysicalDrive2” 打开第三个物理驱动器。

若要获取卷的物理驱动器标识符,请打开卷的句柄,并使用 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS 调用 DeviceIoControl 函数。 此控制代码返回每个卷的一个或多个盘区的磁盘编号和偏移量;卷可以跨越多个物理磁盘。

有关打开物理驱动器的示例,请参阅 调用 DeviceIoControl

打开卷或可移动媒体驱动器(例如软盘驱动器或闪存内存拇指驱动器)时, lpFileName 字符串应采用以下格式:“\\.\X:”。 不要使用尾随反斜杠(\),指示驱动器的根目录。

下表显示了驱动器字符串的一些示例:

字符串 含义
“\.\A:” 打开软盘驱动器 A。
“\.\C:” 打开 C: 卷。
“\.\C:” 打开 C: 卷的文件系统。

还可以通过引用卷名称来打开卷。 有关详细信息,请参阅 命名卷

卷包含一个或多个装载的文件系统。 即使 CreateFile3 中未指定非缓存选项,也可以以非缓存方式打开卷句柄。 应假定所有Microsoft文件系统都以非缓存的形式打开卷句柄。 对文件的非缓存 I/O 的限制也适用于卷。

即使数据未缓存,文件系统也可能不需要缓冲区对齐。 但是,如果在打开卷时指定了非缓存选项,则会强制实施缓冲区对齐方式,而不考虑卷上的文件系统。 建议在所有文件系统上以非缓存方式打开卷句柄,并遵循非缓存 I/O 限制。

注释

 若要读取或写入卷的最后几个扇区,必须调用 DeviceIoControl 并指定 FSCTL_ALLOW_EXTENDED_DASD_IO。 这表示文件系统驱动程序不会对分区读取或写入调用执行任何 I/O 边界检查。 相反,边界检查由设备驱动程序执行。

更改器设备

DeviceIoControlIOCTL_CHANGER_* 控制代码接受变更器设备的句柄。 若要打开更改器设备,请使用以下形式的文件名:“\.\Changerx”,其中 x 是指示要打开的设备的数字,以零开头。 若要在用 C 或C++编写的应用程序中打开 changer 设备零,请使用以下文件名:“\\.\Changer0”。

磁带驱动器

可以使用以下格式的文件名打开磁带驱动器:“\.\TAPEx”,其中 x 是指示要打开的驱动器的数字,从磁带驱动器零开始。 若要在以 C 或 C++ 编写的应用程序中打开磁带驱动器零,请使用以下文件名:“\\.\TAPE0”。

有关详细信息,请参阅备份

通信资源

CreateFile3 函数可以创建通信资源的句柄,例如串行端口 COM1。 对于通信资源,dwCreationDisposition 参数必须OPEN_EXISTING,dwShareMode 参数必须为零(独占访问),并且 hTemplateFile 参数必须为 NULL 可以指定读取、写入或读/写访问权限,并且可以为重叠 I/O 打开句柄。

若要指定大于 9 的 COM 端口号,请使用以下语法:“\.\COM10”。 此语法适用于允许指定 COM 端口号的所有端口号和硬件。

有关通信的详细信息,请参阅 Communications

CreateFile3 函数可以创建控制台输入的句柄(CONIN$)。 如果进程由于继承或重复而具有打开的句柄,则它还可以为活动屏幕缓冲区(CONOUT$)创建句柄。 调用进程必须附加到继承的控制台或 AllocConsole 函数分配的控制台。

对于控制台句柄,请按如下所示设置 CreateFile3 参数:

参数 价值
lpFileName 使用 CONIN$ 值指定控制台输入。

使用 CONOUT$ 值指定控制台输出。

CONIN$ 获取控制台输入缓冲区的句柄,即使 SetStdHandle 函数重定向标准输入句柄。 若要获取标准输入句柄,请使用 GetStdHandle 函数。

CONOUT$ 获取活动屏幕缓冲区的句柄,即使 SetStdHandle 重定向标准输出句柄。 若要获取标准输出句柄,请使用 GetStdHandle
dwDesiredAccess GENERIC_READ \| GENERIC_WRITE 是首选,但任一可以限制访问。
dwShareMode 打开 CONIN$时,请指定 FILE_SHARE_READ。 打开 CONOUT$时,请指定 FILE_SHARE_WRITE

如果调用进程继承控制台,或者子进程应能够访问控制台,则此参数必须为 FILE_SHARE_READ \| FILE_SHARE_WRITE
dwCreationDisposition 使用 CreateFile3 打开控制台时,应指定OPEN_EXISTING

设置在 pCreateExParams 参数中传递的 CREATEFILE3_EXTENDED_PARAMETERS 结构的成员,如下所示:

成员 价值
lpSecurityAttributes 如果希望继承控制台,则SECURITY_ATTRIBUTES结构的 bInheritHandle 成员必须是 TRUE
dwFileAttributes
dwFileFlags
dwSecurityQosFlags
hTemplateFile
忽视。

下表显示了 dwDesiredAccesslpFileName 的各种设置:

lpFileName dwDesiredAccess 结果
“CON” GENERIC_READ 打开控制台进行输入。
“CON” GENERIC_WRITE 打开控制台进行输出。
“CON” GENERIC_READ \| GENERIC_WRITE 导致 CreateFile3 失败; GetLastError 返回 ERROR_FILE_NOT_FOUND

Mailslots

如果 CreateFile3 打开 mailslot 的客户端端,则函数将返回 INVALID_HANDLE_VALUE 如果 mailslot 客户端尝试在 mailslot 服务器使用 CreateMailSlot 函数创建本地 mailslot 之前打开本地 mailslot

有关详细信息,请参阅 Mailslots

管道

如果 CreateFile3 打开命名管道的客户端端,该函数将使用处于侦听状态的命名管道的任何实例。 打开过程可以根据需要多次复制句柄,但在打开句柄后,命名管道实例无法由另一个客户端打开。 打开管道时指定的访问必须与 CreateNamedPipe 函数的 dwOpenMode 参数中指定的访问兼容。

如果在此作之前未在服务器上成功调用 CreateNamedPipe 函数,则管道将不存在, 并且 CreateFile3 将失败 并ERROR_FILE_NOT_FOUND

如果至少有一个活动管道实例,但服务器上没有可用的侦听器管道,这意味着所有管道实例当前都已连接, 则 CreateFile3 会失败并 ERROR_PIPE_BUSY

有关详细信息,请参阅 管道

要求

要求 价值
最低支持的客户端 Windows 11 24H2 [桌面应用 |UWP 应用]
支持的最低服务器 Windows Server 2025 [桌面应用 |UWP 应用]
标头 fileapi.h (包括 Windows.h)
图书馆 Kernel32.lib
DLL Kernel32.dll

另请参阅

CreateDirectory2

DeleteFile2

RemoveDirectory2