CreateFileW 函数 (fileapi.h)

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

若要将此操作作为事务处理操作执行,这会导致可用于事务处理 I/O 的句柄,请使用 CreateFileTransacted 函数。

语法

HANDLE CreateFileW(
  [in]           LPCWSTR               lpFileName,
  [in]           DWORD                 dwDesiredAccess,
  [in]           DWORD                 dwShareMode,
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  [in]           DWORD                 dwCreationDisposition,
  [in]           DWORD                 dwFlagsAndAttributes,
  [in, optional] HANDLE                hTemplateFile
);

参数

[in] lpFileName

要创建或打开的文件或设备的名称。 可以在此名称中使用正斜杠 (/) 或反斜杠 (\)。

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

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

默认情况下,名称限制为MAX_PATH个字符。 若要将此限制扩展到 32,767 宽字符,请将“\\?\”前面追加到路径。 有关详细信息,请参阅 命名文件、路径和命名空间

提示

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

[in] dwDesiredAccess

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

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

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

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

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

[in] dwShareMode

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

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

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

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

注意 每个打开句柄的共享选项一直有效,直到该句柄关闭,而不考虑进程上下文。
价值 意义
0
0x00000000
如果请求删除、读取或写入访问权限,则阻止对文件或设备上的后续打开操作。
FILE_SHARE_DELETE
0x00000004
启用对文件或设备上的后续打开操作以请求删除访问权限。

否则,如果文件或设备请求删除访问权限,则任何进程都无法打开该文件或设备。

如果未指定此标志,但文件或设备已打开以删除访问权限,则函数将失败。

注释 删除访问权限允许删除和重命名操作。
FILE_SHARE_READ
0x00000001
允许对文件或设备执行后续打开操作以请求读取访问权限。

否则,如果文件或设备请求读取访问权限,则任何进程都无法打开该文件或设备。

如果未指定此标志,但已打开文件或设备进行读取访问,则函数将失败。

FILE_SHARE_WRITE
0x00000002
允许对文件或设备执行后续打开操作以请求写入访问权限。

否则,如果文件或设备请求写入访问权限,则任何进程都无法打开该文件或设备。

如果未指定此标志,但已打开文件或设备进行写入访问或具有写入访问权限的文件映射,则函数将失败。

[in, optional] lpSecurityAttributes

指向包含两个独立但相关数据成员的 SECURITY_ATTRIBUTES 结构的指针:可选的安全描述符,以及一个布尔值,该值确定是否可由子进程继承返回的句柄。

此参数可以 NULL

如果此参数 NULL,则应用程序可能创建的任何子进程都无法继承由 CreateFile 返回的句柄,并且与返回的句柄关联的文件或设备将获取默认的安全描述符。

结构的 lpSecurityDescriptor 成员指定文件或设备的 SECURITY_DESCRIPTOR。 如果此成员 NULL,则会为与返回的句柄关联的文件或设备分配一个默认的安全描述符。

CreateFile 打开现有文件或设备时忽略 lpSecurityDescriptor 成员,但继续使用 bInheritHandle 成员。

bInheritHandle 结构的成员指定是否可以继承返回的句柄。

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

[in] 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 参数的一部分。

[in] dwFlagsAndAttributes

文件或设备属性和标志,FILE_ATTRIBUTE_NORMAL 是文件最常见的默认值。

此参数可以包含可用文件属性的任意组合(FILE_ATTRIBUTE_*)。 所有其他文件属性都替代 FILE_ATTRIBUTE_NORMAL

此参数还可以包含标志(FILE_FLAG_)的组合,用于控制文件或设备缓存行为、访问模式和其他特殊用途标志。 这些值与任何 FILE_ATTRIBUTE_ 值结合使用。

此参数还可以通过指定 SECURITY_SQOS_PRESENT 标志来包含安全服务质量(SQOS)信息。 下表中显示了与 SQOS 相关的其他标志信息,这些属性和标志表如下。

注释CreateFile 打开现有文件时,它通常会将文件标志与现有文件的文件属性合并,并忽略作为 dwFlagsAndAttributes的 一部分提供的任何文件属性。 创建和打开文件中详细介绍了特殊情况。
以下某些文件属性和标志可能仅适用于文件,不一定适用于所有 CreateFile 的其他类型的设备。 有关详细信息,请参阅本主题的“备注”部分,创建和打开文件

有关对文件属性的更高级访问,请参阅 SetFileAttributes。 有关所有文件属性及其值和说明的完整列表,请参阅 文件属性常量

属性 意义
FILE_ATTRIBUTE_ARCHIVE
32 (0x20)
该文件应存档。 应用程序使用此属性标记文件以供备份或删除。
FILE_ATTRIBUTE_ENCRYPTED
16384 (0x4000)
文件或目录已加密。 对于文件,这意味着文件中的所有数据都已加密。 对于目录,这意味着加密是新创建的文件和子目录的默认值。 有关详细信息,请参阅 文件加密

如果还指定了 FILE_ATTRIBUTE_SYSTEM,则此标志无效。

家庭版、家庭高级版、入门版或 ARM 版 Windows 不支持此标志。

FILE_ATTRIBUTE_HIDDEN
2 (0x2)
文件已隐藏。 不要将其包含在普通目录列表中。
FILE_ATTRIBUTE_NORMAL
128 (0x80)
该文件没有设置其他属性。 仅当单独使用时,此属性才有效。
FILE_ATTRIBUTE_OFFLINE
4096 (0x1000)
文件的数据不会立即可用。 此属性指示文件数据在物理上移动到脱机存储。 此属性由远程存储(分层存储管理软件)使用。 应用程序不应任意更改此属性。
FILE_ATTRIBUTE_READONLY
1 (0x1)
该文件是只读的。 应用程序可以读取文件,但无法写入或删除该文件。
FILE_ATTRIBUTE_SYSTEM
4 (0x4)
该文件是操作系统的一部分或独占使用。
FILE_ATTRIBUTE_TEMPORARY
256 (0x100)
该文件用于临时存储。

有关详细信息,请参阅本主题的 缓存行为 部分。

意义
FILE_FLAG_BACKUP_SEMANTICS
0x02000000
正在为备份或还原操作打开或创建该文件。 当进程具有 SE_BACKUP_NAMESE_RESTORE_NAME 特权时,系统可确保调用进程替代文件安全检查。 有关详细信息,请参阅 更改令牌中的特权。

必须设置此标志才能获取目录的句柄。 目录句柄可以传递给某些函数,而不是文件句柄。 有关详细信息,请参阅“备注”部分。

FILE_FLAG_DELETE_ON_CLOSE
0x04000000
文件将在关闭所有句柄后立即删除,其中包括指定的句柄和任何其他打开或重复的句柄。

如果文件存在现有的打开句柄,则调用将失败,除非它们都以 FILE_SHARE_DELETE 共享模式打开。

文件的后续打开请求失败,除非指定了 FILE_SHARE_DELETE 共享模式。

FILE_FLAG_NO_BUFFERING
0x20000000
文件或设备正在打开,没有数据读取和写入的系统缓存。 此标志不会影响硬盘缓存或内存映射文件。

使用 FILE_FLAG_NO_BUFFERING 标志成功处理使用 CreateFile 打开的文件有严格的要求,有关详细信息,请参阅 文件缓冲

FILE_FLAG_OPEN_NO_RECALL
0x00100000
请求文件数据,但它应继续位于远程存储中。 不应将其传输回本地存储。 此标志供远程存储系统使用。
FILE_FLAG_OPEN_REPARSE_POINT
0x00200000
正常 重新分析点 处理不会发生;CreateFile 将尝试打开重新分析点。 打开文件时,将返回文件句柄,无论控制重新分析点的筛选器是否正常运行。

此标志不能与 CREATE_ALWAYS 标志一起使用。

如果文件不是重新分析点,则忽略此标志。

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

FILE_FLAG_OVERLAPPED
0x40000000
文件或设备正在为异步 I/O 打开或创建。

在此句柄上完成后续 I/O 操作时,OVERLAPPED 结构中指定的事件将设置为信号状态。

如果指定了此标志,则文件可用于同时读取和写入操作。

如果未指定此标志,则会序列化 I/O 操作,即使对读取和写入函数的调用指定了 重叠 结构也是如此。

有关使用此标志创建的文件句柄时的注意事项,请参阅本主题的 同步和异步 I/O 句柄 部分。

FILE_FLAG_POSIX_SEMANTICS
0x01000000
访问将按照 POSIX 规则进行。 这包括允许具有名称的多个文件,仅在支持该命名的文件系统时有所不同。 使用此选项时请小心,因为使用此标志创建的文件可能无法由为 MS-DOS 或 16 位 Windows 编写的应用程序访问。
FILE_FLAG_RANDOM_ACCESS
0x10000000
访问旨在随机访问。 系统可以将其用作优化文件缓存的提示。

如果文件系统不支持缓存的 I/O 并 FILE_FLAG_NO_BUFFERING,则此标志无效。

有关详细信息,请参阅本主题的 缓存行为 部分。

FILE_FLAG_SESSION_AWARE
0x00800000
正在打开具有会话感知的文件或设备。 如果未指定此标志,则会话中运行的进程无法打开每个会话设备(例如使用 RemoteFX USB 重定向的设备)。 此标志对会话 0 中不具有调用方的影响。 此标志仅在 Windows 的服务器版本上受支持。

Windows Server 2008 R2 和 Windows Server 2008:Windows Server 2012 之前不支持此标志。

FILE_FLAG_SEQUENTIAL_SCAN
0x08000000
Access 旨在从头到尾的顺序。 系统可以将其用作优化文件缓存的提示。

如果使用读后(即反向扫描),则不应使用此标志。

如果文件系统不支持缓存的 I/O 并 FILE_FLAG_NO_BUFFERING,则此标志无效。

有关详细信息,请参阅本主题的 缓存行为 部分。

FILE_FLAG_WRITE_THROUGH
0x80000000
写入操作不会经历任何中间缓存,它们将直接转到磁盘。

有关详细信息,请参阅本主题的 缓存行为 部分。

dwFlagsAndAttributes 参数还可以指定 SQOS 信息。 有关详细信息,请参阅 模拟级别。 当调用应用程序将 SECURITY_SQOS_PRESENT 标志指定为 dwFlagsAndAttributes的一部分时,它还可以包含以下一个或多个值。

安全标志 意义
SECURITY_ANONYMOUS
在匿名模拟级别模拟客户端。
SECURITY_CONTEXT_TRACKING
安全跟踪模式是动态的。 如果未指定此标志,则安全跟踪模式是静态的。
SECURITY_DELEGATION
在委派模拟级别模拟客户端。
SECURITY_EFFECTIVE_ONLY
只有客户端安全上下文的启用方面可供服务器使用。 如果未指定此标志,则客户端安全上下文的所有方面都可用。

这允许客户端限制服务器在模拟客户端时可以使用的组和特权。

SECURITY_IDENTIFICATION
在标识模拟级别模拟客户端。
SECURITY_IMPERSONATION
在模拟级别模拟客户端。 如果未指定其他标志以及 SECURITY_SQOS_PRESENT 标志,则这是默认行为。

[in, optional] hTemplateFile

具有 GENERIC_READ 访问权限的模板文件的有效句柄。 模板文件为正在创建的文件提供文件属性和扩展属性。

此参数可以 NULL

打开现有文件时,CreateFile 忽略此参数。

打开新的加密文件时,该文件从其父目录继承自由访问控制列表。 有关详细信息,请参阅 文件加密

返回值

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

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

言论

CreateFile 最初是为文件交互而开发的,但后来进行了扩展和增强,以包括 Windows 开发人员可用的大多数其他类型的 I/O 设备和机制。 本部分尝试介绍开发人员在不同上下文和不同 I/O 类型中使用 CreateFile 时可能会遇到的各种问题。 仅当专门引用存储在文件系统上实际文件中的数据时,文本才会尝试使用单词 文件。 但是,文件的一些用法 可能更普遍地引用支持类似文件的机制的 I/O 对象。 由于前面提到的历史原因,此术语 文件 在常量名称和参数名称中特别普遍。

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

Windows Server 2003 和 Windows XP:如果尝试打开文件或目录以在远程计算机上删除,尝试打开文件或目录以在远程计算机上删除,则当 dwDesiredAccess 参数的值是 DELETE 访问标志(0x00010000)OR“与任何其他访问标志一起”时,会发生共享冲突, 并且远程文件或目录尚未使用 FILE_SHARE_DELETE打开。 为了避免在此方案中发生共享冲突,请使用 DELETE 打开远程文件或目录 访问权限,或者调用 DeleteFile,而无需先打开文件或目录进行删除。

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

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

Windows Server 2003 和 Windows XP:出于向后兼容性目的,CreateFilelpSecurityAttributes中指定安全描述符时,不会应用继承规则。 为了支持继承,以后查询此文件的安全描述符的函数可能会启发式确定并报告继承是否有效。 有关详细信息,请参阅 可继承 ACE 的自动传播

如前所述,如果 lpSecurityAttributes 参数 NULL,则 CreateFile 返回的句柄不能由应用程序可能创建的任何子进程继承。 有关此参数的以下信息也适用:

  • 如果 bInheritHandle 成员变量未 FALSE(任何非零值),则可以继承句柄。 因此,如果不希望句柄可继承,则必须将此结构成员正确初始化为 FALSE
  • 文件或目录的默认安全描述符中的访问控制列表(ACL)继承自其父目录。
  • 目标文件系统必须支持 lpSecurityDescriptor 成员对文件和目录的安全性,才能对其产生影响,这可以通过使用 GetVolumeInformation来确定。
在 Windows 8 和 Windows Server 2012 中,以下技术支持此函数。
科技 支持
服务器消息块 (SMB) 3.0 协议 是的
SMB 3.0 透明故障转移 (TFO) 请参阅备注
具有横向扩展文件共享的 SMB 3.0 (SO) 请参阅备注
群集共享卷文件系统 (CsvFS) 是的
可复原文件系统 (ReFS) 是的

请注意,如果对已打开的备用数据流的文件执行 ,则具有取代处置的 CreateFile 将失败。

符号链接行为

如果对此函数的调用创建文件,则行为没有变化。 此外,请考虑有关 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,受影响的文件就是目标。

缓存行为

CreateFile 使用 dwFlagsAndAttributes 参数的几个可能值来控制或影响系统缓存与句柄关联的数据的方式。 它们是:
  • FILE_FLAG_NO_BUFFERING
  • FILE_FLAG_RANDOM_ACCESS
  • FILE_FLAG_SEQUENTIAL_SCAN
  • FILE_FLAG_WRITE_THROUGH
  • FILE_ATTRIBUTE_TEMPORARY
如果未指定这些标志,系统将使用默认的常规用途缓存方案。 否则,系统缓存的行为为每个标志指定。

不应合并其中一些标志。 例如,将 FILE_FLAG_RANDOM_ACCESSFILE_FLAG_SEQUENTIAL_SCAN 相结合是自败。

指定 FILE_FLAG_SEQUENTIAL_SCAN 标志可以提高使用顺序访问读取大型文件的应用程序的性能。 对于主要按顺序读取大型文件的应用程序,性能提升可能更为明显,但偶尔会跳过小范围的字节。 如果应用程序移动文件指针进行随机访问,则很可能不会出现最佳缓存性能。 但是,仍可以保证正确的操作。

FILE_FLAG_WRITE_THROUGHFILE_FLAG_NO_BUFFERING 的标志是独立的,可以组合使用。

如果使用 FILE_FLAG_WRITE_THROUGH 但未指定 FILE_FLAG_NO_BUFFERING,以便系统缓存生效,则数据将写入系统缓存,但不会延迟地刷新到磁盘。

如果同时指定了 FILE_FLAG_WRITE_THROUGHFILE_FLAG_NO_BUFFERING,以便系统缓存无效,则数据会立即刷新到磁盘,而无需通过 Windows 系统缓存。 操作系统还向永久性媒体请求硬盘本地硬件缓存的写入。

注意 并非所有硬盘硬件都支持此写通功能。
正确使用 FILE_FLAG_NO_BUFFERING 标志需要特殊的应用程序注意事项。 有关详细信息,请参阅 文件缓冲

通过 FILE_FLAG_WRITE_THROUGH 的写通请求还会导致 NTFS 刷新任何元数据更改,例如时间戳更新或重命名操作,这会导致处理请求。 因此,FILE_FLAG_WRITE_THROUGH 标志通常与 FILE_FLAG_NO_BUFFERING 标志一起使用,作为每次写入后调用 FlushFileBuffers 函数的替代项,这可能会导致不必要的性能损失。 将这些标志一起使用可避免这些处罚。 有关文件和元数据缓存的一般信息,请参阅 文件缓存

FILE_FLAG_NO_BUFFERINGFILE_FLAG_OVERLAPPED结合使用时,标志可提供最大的异步性能,因为 I/O 不依赖于内存管理器的同步操作。 但是,某些 I/O 操作需要更多时间,因为缓存中未保存数据。 此外,文件元数据仍可能缓存(例如,创建空文件时)。 若要确保将元数据刷新到磁盘,请使用 FlushFileBuffers 函数。

指定 FILE_ATTRIBUTE_TEMPORARY 属性会导致文件系统避免在有足够的缓存内存可用时将数据写回到大容量存储,因为应用程序在关闭句柄后删除临时文件。 在这种情况下,系统可以完全避免写入数据。 尽管它不直接控制数据缓存的方式与前面提到的标志相同,但 FILE_ATTRIBUTE_TEMPORARY 属性确实会告知系统在系统缓存中尽可能多地保存而不编写数据缓存,因此可能对某些应用程序感到担忧。

文件

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

如果由于对 DeleteFile的上一次调用而挂起删除的文件调用 CreateFile,该函数将失败。 操作系统会延迟文件删除,直到文件的所有句柄都关闭。 GetLastError 返回 ERROR_ACCESS_DENIED

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

如果指定了 CREATE_ALWAYSFILE_ATTRIBUTE_NORMALCreateFile 将失败,并将文件存在且具有 FILE_ATTRIBUTE_HIDDENFILE_ATTRIBUTE_SYSTEM 属性时将最后一个错误设置为 ERROR_ACCESS_DENIED。 若要避免此错误,请指定与现有文件相同的属性。

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

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

同步和异步 I/O 句柄

CreateFile 提供用于创建同步或异步的文件或设备句柄。 同步句柄的行为使使用该句柄的 I/O 函数调用被阻止,直到它们完成,而异步文件句柄使系统能够立即从 I/O 函数调用返回,无论它们是否已完成 I/O 操作。 如前所述,此同步与异步行为是通过在 dwFlagsAndAttributes 参数中指定 FILE_FLAG_OVERLAPPED 来确定的。 使用异步 I/O 时,存在多种复杂性和潜在缺陷;有关详细信息,请参阅 同步和异步 I/O

文件流

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

目录

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

若要使用 CreateFile打开目录,请将 FILE_FLAG_BACKUP_SEMANTICS 标志指定为 dwFlagsAndAttributes的一部分。 在没有 SE_BACKUP_NAMESE_RESTORE_NAME 特权的情况下使用此标志时,仍适用适当的安全检查。

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

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

物理磁盘和卷

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

Windows Server 2003 和 Windows XP:直接访问磁盘或卷的方式不受限制。

可以使用 CreateFile 函数打开物理磁盘驱动器或卷,该驱动器返回可与 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: 卷的文件系统。

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

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

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

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

变更程序设备

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

磁带驱动器

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

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

通信资源

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

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

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

控制台

CreateFile 函数可以创建控制台输入的句柄(CONIN$)。 如果进程由于继承或重复而具有打开的句柄,则它还可以为活动屏幕缓冲区(CONOUT$)创建句柄。 调用进程必须附加到继承的控制台或由 AllocConsole 函数分配的控制台。 对于控制台句柄,请按如下所示设置 CreateFile 参数。
参数 价值
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此参数。

lpSecurityAttributes 如果希望继承控制台,SECURITY_ATTRIBUTES 结构的 bInheritHandle 成员必须 TRUE
dwCreationDisposition 使用 CreateFile 打开控制台时,应指定 OPEN_EXISTING
dwFlagsAndAttributes 忽视。
hTemplateFile 忽视。

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

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

Mailslots

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

有关详细信息,请参阅 Mailslots

管道

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

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

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

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

例子

以下主题显示了示例文件操作:

以下主题演示了物理设备 I/O: 使用命名管道的示例位于 命名管道客户端

使用 mailslot 会显示 写入 Mailslot

可以在创建备份应用程序找到磁带备份代码片段。

注意

fileapi.h 标头将 CreateFile 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的 约定。

要求

要求 价值
最低支持的客户端 Windows XP [仅限桌面应用]
支持的最低服务器 Windows Server 2003 [仅限桌面应用]
目标平台 窗户
标头 fileapi.h (包括 Windows.h)
Kernel32.lib
DLL Kernel32.dll

另请参阅

关于目录管理

关于卷管理 的

备份

CloseHandle

通信

CreateDirectory

CreateDirectoryEx

CreateFileTransacted

CreateMailSlot

CreateNamedPipe

创建、删除和维护文件

DeleteFile

设备输入和输出控制(IOCTL)

DeviceIoControl

文件压缩和解压缩

文件加密

文件管理功能

文件安全性和访问权限

文件流

函数

GetLastError

I/O 完成端口

I/O 概念

Mailslots

获取和设置文件信息

概述主题

管道

ReadFile

ReadFileEx

使用特殊特权运行的

SetFileAttributes

WriteFile

WriteFileEx