1、CreateFile CreateFile函数创建或打开以下的对象并且返回一个可被对象访问的句柄: l 控制台 l 通信资源 l 目录 l 磁盘驱动 l 文件 l 邮路 l 管道 HANDLE CreateFile( LPCTSTR lpFileName, // 文件名 DWORD dwDesiredAccess, // 访问模式 DWORD dwShareMode, // 共享模式 LPSECURITY_ATTR
2、IBUTES lpSecurityAttributes, // SD DWORD dwCreationDisposition, // 如何创建 DWORD dwFlagsAndAttributes, // 文件属性 HANDLE hTemplateFile // 文件模板句柄 参数 lpFileName 指针指向一个无终止符的字符串指定对象的名称,用以创建或打开。 Windows NT/2000/XP:在ANSI(美国信息标准)版本的函数中,名称限制
3、最大字符串长度。要扩展这个限制以满足大约32000长度的字符串,使用Unicode(统一字符编码标准)版本的函数,并且在路径中预加”\\?\”。更多信息请查看文件名规则。 Windows 95/98/Me: 这个字符串必须不大于最大字符长度。 dwDesiredAccess 指定对象的访问类型。一个应用程序可以获得读访问、写访问、读/写访问或驱动查询访问。这个参量可以被任意的以下参数值组合: 参数值 描述 0 指定驱动查询访问给对象。应用程序能在不需要驱动访问进行时查询驱动属性。 GENERIC_READ 指定读访问给对象。数据能够从文件与可被移动的文件指针读入。与GEN
4、ERIC_WRITE结合可实现读/写访问。 GENERIC_WRITE 指定写访问给对象。数据能够被写入文件和可移动的文件指针。与GENERIC_READ结合可实现读/写访问。 另外,你可以定义以下的访问标志。 参数值 文档 DELETE 标准访问权限 READ_CONTROL 标准访问权限 WRITE_DAC 标准访问权限 WRITE_OWNER 标准访问权限 SYNCHRONIZE 标准访问权限 STANDARD_RIGHTS_REQUIRED 标准访问权限 STANDARD_RIGHTS_READ 标准访问权限 STANDARD_RI
5、GHTS_WRITE 标准访问权限 STANDARD_RIGHTS_EXECUTE 标准访问权限 STANDARD_RIGHTS_ALL 标准访问权限 SPECIFIC_RIGHTS_ALL 访问掩码 ACCESS_SYSTEM_SECURITY 访问掩码 MAXIMUM_ALLOWED 访问掩码 GENERIC_READ 访问掩码 GENERIC_WRITE 访问掩码 GENERIC_EXECUTE 访问掩码 GENERIC_ALL 访问掩码 dwShareMode 指定对象如何被共享。如果dwShareMode为0,并且创建文件成功,对象不能够
6、被共享和再次打开,直到句柄关闭。请参考备注部分关于共享冲突的信息。 为了共享对象,使用一个或多个以下参数值的集合。 参数值 描述 FILE_SHARE_DELETE Windows NT/2000/XP:只有当删除访问请求时,随后在对象上的打开操作才能成功。 FILE_SHARE_READ 只有当读访问被请求时,随后在对象上的打开操作才能成功。 FILE_SHARE_WRITE 只有当写访问被请求时,随后在对象上的打开操作才能成功。 lpSecurityAttributes 指针指向一个SECURITY ATTRIBUTES结构体决定句柄返回是否能够被子
7、过程继承。如果lpSecurityAttributes为NULL,那么句柄不能被继承。 Windows NT/2000/XP: 结构体lpSecurityDescriptor的成员为对象指定一个安全的描述符。如果lpSecurityAttributes为NULL,那么对象得到一个默认的安全描述符。目标文件系统必须支持在文件和目录的安全性,以支持这个参数在文件上的影响。 dwCreationDisposition 指定文件的创建方式,并且当文件不存在时指定文件的常见方式。关于这个参数的跟多信息请参考备注信息。这个参数必须赋予以下值。 参数值 描述 CREATE_NEW
8、建立一个新文件,如果文件已经存在,将出现函数错误。 CREATE_ALWAYS 创建一个新文件,如果文件已经存在,将覆盖原来的文件,清除现有的属性,并且用dwFlagsAndAttributes与FILE_ATTRIBUTE_ARCHIVE混合文件属性和已定义标志。 OPEN_EXISTING 打开文件。如果文件不存在,将出现函数错误。 关于为什么你需要用OPEN_EXISTING标记如果你正在使用CreateFile函数在驱动时的讨论,请参考备注。 OPEN_ALWAYS 如果文件存在,打开文件。如果不存在,函数像dwCreationDisposition为 CREATE_
9、NEW一样创建文件。 TRUNCATE_EXISTING 打开文件。一旦打开,文件被截断以便使其为0字节。正在调用的过程必须打开至少是GENRIC_WRITE访问的文件。如果文件不存在,函数错误。 dwFlagsAndAttributes 为文件指定文件属性和标记。 在dwFlagsAndAttributes参数中,任何以下属性的组合是被接受的,所有其他文件属性替代FILE_ATTRIBUTE_NORMAL属性除外. 属性 描述 FILE_ATTRIBUTE_ARCHIVE 文件被标记归档。应用程序使用这个属性标记文件备份或移除。 FILE_ATTRIBUTE_E
10、NCRYPTED 文件或目录标记为加密。对一个文件而言,这个含义表示文件中的所有的数据被加密。对目录而言,这个含义表示对新创建的文件和子目录加密方法为默认属性。 如果FILE_ATTRIBUTE_SYSTEM也被定义,这个标记将无影响。 FILE_ATTRIBUTE_HIDDEN 文件为隐藏。它不包括在一个普通的目录列表中。 FILE_ATTRIBUTE_NORMAL 文件没有其他属性设置。当这个属性单独使用时有效。 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 文件将正在内容索引服务中被索引。 FILE_ATTRIBUTE_OFFLINE 文件
11、数据不能立即使用。这个属性表明文件数据已经被物理移动至脱机存储器中。这个属性被使用在远程存储器、分层存储器存储管理软件中。应用程序不能随意改变此属性。 FILE_ATTRIBUTE_READONLY 文件只读。应用程序能够读文件,但不能写或删除文件。 FILE_ATTRIBUTE_SYSTEM 部分文件或全部被操作系统使用 FILE_ATTRIBUTE_TEMPORARY 文件正在被临时存储器调用。文件系统与其试图使在内存中的所有数据存入大容量存储器倒不如更迅速地被访问。 对dwFlagsAndAttributes参数来说,以下任何标记的组合是可以允许的。 标记 描述
12、FILE_FLAG_WRITE_THROUGH 命令系统通过任意中级缓存并且直接写入磁盘。系统仍能隐藏写操作,但是不能缓慢的强制刷新。 FILE_FLAG_OVERLAPPED 命令系统初始化对象,以获得一个有意义的时间数值来处理ERROR_IO_PENDING返回。当操作完成,指定的设置被设置为规定信号。 当你指定FILE_FLAG_OVERLAPPED,文件读与写函数必须指定为OVERLAPPED结构。就是说,当FILE_FLAG_OVERLAPPED已被指定,一个应用程序必须提供异步读和写。 当FILE_FLAG_OVERLAPPED已被指定,系统不维持文件指针。文件位
13、置以lpOverlapped属性(指向一个OVERLAPPED结构)被传递,用以文件读写函数。 这个标记也能使不止一个操作与句柄(例如一个联合读与写的操作)联立地执行。 FILE_FLAG_NO_BUFFERING 命令系统不需要中间缓存或高速缓存打开文件。当联合使用FILE_FLAG_OVERLAPPED,标记给予最大的异步性能,因为I/O不依赖内存管理的同步操作。然而,一些I/O操作将更久,因为数据不被置入高速缓存中。 当运行伴随已打开文件且有FILE_FLAG_NO_BUFFERING属性时,应用程序必然出现某些必要需要: l 文件访问必须开始于在整数倍文件扇区大小
14、内的字节偏移。 l 文件访问一定是许多整数倍文件扇区大小的字节。例如,如果扇区大小为512字节,应用程序能够请求读和写512、1024或2048字节,但是不能是335、981、或7171字节。 l 缓存区地址的读写操作与扇区对齐(对齐整数倍扇区大小的内存地址)。依赖于磁盘,这个要求可能不会被强制执行。 一种调整缓冲区为整数倍扇区大小值的方法是使用VirtualAlloc分配缓冲区。它调整地址以整数倍的操作系统内存页大小分配内存。因为内存页与扇区卷标大小二者之间后者更高级,因此内存地址也对齐整数倍的扇区容量大小。 应用程序能通过GetDiskFreeSpace函数确定扇区大小。
15、 FILE_FLAG_RANDOM_ACCESS 指示文件随机存取。系统可以利用这个作为优化文件缓存的提示。 FILE_FLAG_SEQUENTIAL_SCAN 指示文件从开始到结尾顺序存储。系统可以利用这个作为优化文件缓存的提示。如果应用程序以随机访问移动文件指针,最适合的高速缓存不一定产生;然而,正确的操作仍然是有保证的。 在连续访问模式,定义这个标记能增强应用程序的读大文件的性能。在应用程序读顺序地读大文件时性能收益能甚至更显而易见,但是偶尔会跳过小字节区间。 FILE_FLAG_DELETE_ON_CLOSE 指示操作系统在它的句柄被关闭后立即删除文件,不仅仅是处理你所
16、指定FILE_FLAG_DELETE_ON_CLOSE属性的句柄。 随后的文件打开请求将失败,除非FILE_SHARE_DELETE被使用。 FILE_FLAG_BACKUP_SEMANTICS Windows NT/2000/XP: 指示一个已被打开或创建文件的备份或恢复。假若它已有必要的权限,系统将确保调用过程不进行文件安全检测。相关的权限如SE_BACKUP_NAME和SE_RESTORE_NAME。 你也能够设置这个标记用以获取一个目录的句柄。一个目录句柄能够传递给一些代替文件句柄的函数。 FILE_FLAG_POSIX_SEMANTICS 指示文件权限符合POSI
17、X规则。包括假如文件系统支持文件的多个不同名称的命名。谨慎使用则个选项,因为使用这个标记创建文件可能不能被MS-DOS或16位Windows应用程序的写操作接受。 FILE_FLAG_OPEN_REPARSE_POINT 设置这个标记禁止NTFS解析点重新解析操作。当文件已被打开,无论控制解析点是否被操作,文件句柄都会被返回。这个标记不能与CREATE_ALWAYS标记一同使用。 FILE_FLAG_OPEN_NO_RECALL 指示文件数据被请求,但是它应当贮存在远程存储器中。它不能被存入特定的逻辑存储器中。这个标记特别用于远程存储器系统或远程存储器管理系统中。 如果Create
18、File函数打开一个已命名通道的客户端,dwFlagsAndAttributes参数也能够包含安全服务中的安全质量服务信息。更多的信息,参考Impersonation Levels。当应用程序调用指定为SECURITY_SQOS_PRESENT标记,dwFlagsAndAttributes参数能够包含一个或多个以下的参数值。 参数 描述 SECURITY_ANONYMOUS 指定在Identification模拟等级中模拟客户端。 SECURITY_IDENTIFICATION 指定在Identification模拟等级中模拟客户端。 SECURITY_IMPERSONATION
19、 指定在Identification模拟等级中模拟客户端。 SECURITY_DELEGATION 指定在Delegation模拟等级中模拟客户端。 SECURITY_CONTEXT_TRACKING 指定安全追踪模式是动态的。如果这个标记未被定义,安全追踪模式是静态的。 SECURITY_EFFECTIVE_ONLY 只有当用户的安全上下文方面是可激活的,则在服务器中有效。如果你不指定这个标记,所有的用户安全上下文是有效地。 这个标记允许客户端限制分组和权限, 那么一个正在模拟客户端服务器可以使用。 hTemplateFile 指示一个GENERIC_READ句柄
20、接受一个模版文件。这个模版文件提供正在创建文件的文件属性与扩展属性。 Windows 95/98/Me: hTemplateFile参数必须为NULL。如果你提供一个句柄,则调用失败,GetLastError返回ERROR_NOT_SUPPORTED。 Return Valuse 如果函数成功,返回值是一个指定文件的打开句柄。如果指定的文件在函数调用并且dwCreationDisposition为CREATE_ALWAYS或OPEN_ALWAYS之前存在,GetLastError返回ERROR_ALREADY_EXISTS(即使函数是成功的)。如果文件在调用前不存在,GetLastE
21、rror返回0. 如果函数失败,返回值为INVALID_HANDLE_VALUE。得到扩展错误信息,调用GetLastError。 备注 使用CloseHandle函数关闭一个对象句柄,并通过CreateFile返回。 如以下注明,对dwDesiredAccess付0值,允许应用程序查询设备而不需要实际上的访问设备。这种查询方式是有意义的,例如,如果一个应用程序想要确定磁盘驱动器的大小和格式化支持,不需要软盘插入驱动器。 Windows 95/98/ME:CreateFileW通过微软统一字符编码标准结构支持。为了使用这个标准,你必须为你的应用程序加载某些文件,如
22、在Windows 95/98/Me微软同意字符编码标准结构系统概述。 Windows 2000/XP:如果当dwDesiredAccess参数值为DELETE或’ed,且联同其他任何访问标记,并且远程文件或目录没有以FILE_SHARE_DELETE共享访问时,在远程机器上为删除一个打开文件或目录意图一个共享冲突将发生。为了避免共享冲突在这种局面中出现,只用DELETE访问或为了删除不在第一次打开文件或目录时调用DeleteFile打开远程文件或目录。 Windows 2000/XP:如果CREATE_ALWAYS作为dwCreationDisposition参数值被定义且FILE
23、ATTRIBUTE_NORMAL未被作为dwFlagsAndAttributes的参数值定义,CreateFile将失败并设置GetLastError错误报告给ACCESS_DENIED。假若如此,设置dwFlagsAndAttributes的参数值中FILE_ATTRIBUTE_HIDDEN和FILE_ATTRIBUTE_NORMAL属性为ORed以避免这个错误。 文件 如果你意图在一个软盘驱动器中或在光盘驱动器中创建一个文件且不没有一个软盘或光盘,系统显示一个消息窗口告诉用户分别需要插入一个软盘或光盘,为了防止系统显示这个消息框,联同SEM_FAILCRITICALERROR
24、S调用SetErrorMode函数。 当建立一个新文件时,CreateFile函数执行以下的操作: l 清除现有的文件属性。 l 联合文件属性和被dwFlagsAndAttributes的FILE_ATTRIBUTE_ARCHIVE指定的而标记。 l 设置文件长度为0。 l 如果hTemplateFile参数被定义,复制模版文件提供的文件属性给新文件。 当打开一个现有的文件时,CreateFile执行以下的操作: l 联合被现有的文件属性的dwFlagsAndAttributes 指定的标记。CreateFile忽略被dwFlagsAndAttributes定义的
25、文件属性。 l 根据dwCreationDisposition定义的值设置文件的长度。 l 忽略hTemplateFile参数。 l 如果lpSecurityAttributes参数不为NULL,忽略SECURITY ATTRIBUTES结构体的lpSecurityDescriptor成员参数。其他结构体的成员为已用的。bInheritHandle成员是指示文件句柄是否被继承唯一的方式 。 Windows NT/2000/XP:如果你重命名或删除一个文件,那么随后恢复它 ,系统搜寻缓存文件信息以恢复。隐藏信息包含它的长/短名称对和创建时间。 Windows NT/2000/X
26、P:文件系统,如NTFS,支持个别文件和目录压缩或加密。在格式化卷标这样一个文件系统中,一个文件继承它的目录压缩与加密属性。 你不能使用CreateFile函数以设置一个文件的压缩状态。使用DeviecIoControl函数以设置文件压缩状态。 当多数过程想要打开相同的文件,或者单个过程想要几次打开文件,如果第二次并且随后的操作定义任意一个共享模式与第一次打开方式访问模式定义不同,一个共享冲突将在文件打开的第一时间发生。换句话说,Windows 不能允许在多次单个文件的打开操作中的共享模式请求冲突。 两个关于共享冲突的例子如下: l 如果在第一次调用CreateFile
27、时定义GENERIC_READ、GENERIC_WRITE访问模式与FILE_SHARE_READ共享模式。如果你在第二次调用CreateFile时定义了GENERIC_WRITE访问模式,那么函数将因为一个共享冲突而失败,原因是第一次调用打开文件时为仅仅读模式。 l 如果在第一次调用CreateFile时定义GENERIC_READ、GENERIC_WRITE访问模式,FILE_SHARE_READ和FILE_SHARE_WRITE共享模式。如果在第二次调用CreateFile时仅定义GENERIC_READ 、GENERIC_WRITE访问模式和FILE_SHARE_READ共享模式,函
28、数将因为一个共享冲突失败,原因是第二次调用与读/写访问与第一次赋予的仅仅读共享模式冲突。 管道 如果CreateFile打开一个完成于已命名管道的客户端,函数使用任何已命名管道的实例监听状态。开放的过程能按需多次复制句柄,一旦打开,已命名的管道实例不能被其他客户端打开。当一个管道被打开时,其打访问定义必须与CreateNamedPipe函数dwOpenMode参数的访问定义不同。更多关于管道的信息,参考Pipes。 邮槽 如果CreateFile打开一个完成于邮槽的客户端,如果在包括CreateMailSlot函数的邮槽服务被创建以前邮槽客户端企图打开一个逻辑邮槽时,函
29、数返回INVALID_HANDLE_VALUE。更多关于邮槽的信息,参考Mailslots。 通信资源 CreateFile函数能为通信资源创建一个句柄,如串口COM1。对通信资源来说,dwCreationDisposition参数必须为OPEN_EXISTING,并且hTemplate参数必须为NULL。读、写或读/写访问能被定义,且对异步I/O句柄可以被打开。更多关于通信的信息,参考Communications。 磁盘驱动器 卷标句柄可能被当做文件系统任凭不进行缓存打开,即使当不进行缓存选项没有被CreateFile定义,你应该假定微软文件系统以不缓存打开卷标句柄。
30、文件的不进行缓存的I/O限制也适用于卷标。 Windows NT/2000/XP:你能使用CreateFile函数以打开一个磁盘驱动器或在一个磁盘驱动器上的分区。函数给磁盘驱动器返回一个句柄;这个句柄能同DeviceIOControl函数被使用。以下的必要条件必须被关注以调用成功: l 对操作来说调用程序必须有管理权限以在硬盘驱动器以调用成功。 l lpFileName应该被格式为\\.\PHYSICALDRIVEx字符串以打开硬盘 x。硬盘成员开始于0。例如: 字符串 含义 \\.\PHYSICALDRIVE2 在用户计算机中,从第三个物理驱动器获得一个句柄 如何打开
31、一个物理驱动器的实例,参考Calling DeviceIoControl on Windows NT/2000. l lpFileName字符串应该为\\.\x:以打开软盘驱动器x或在硬盘上的x分区。例如: 字符串 含义 \\.\A: 在用户计算机上获得一个驱动器A的句柄 \\.\C: 在用户计算机上获得一个驱动器C的句柄 在一个驱动器名最后没有反斜杠。字符串\\.\c:\表示C驱动器下的根目录。 在Windows 2000或更早版本中,你也可以打开一个卷标通过它的唯一的卷标名。假若如此,那么在唯一的卷标明后没有最后反斜杠。 所有的I/O缓存应该与扇区
32、对齐(在内存中对齐地址为整数倍的扇区容量大小),甚至如果磁盘驱动器没有FLIE_FLAG_NO_BUFFERING标记被打开。依赖磁盘这个要求可能不被强制。 Windows 95/98/ME:在打开逻辑驱动器时,这个技术不运作。指定一个格式化的字符串导致CreateFile返回一个错误。 l dwCreationDisposition参数必须包含OPEN_EXISTING值。 l 当打开一个软盘驱动器或一个硬盘分区,你必须在dwShareMode参数中设置FILE_SHARE_WRITE标记。 磁带驱动器 Windows NT/2000/XP:你能可以使用一个格式化的
33、文件名 \\.\TAREx打开磁带驱动器,x是一个数值指针要打开的驱动器,起始为磁带驱动器0.为在C中打开磁带驱动器0,使用文件名\\\\.\\TAPE0。更多关于备份磁带驱动器或应用程序的信息,参考Tape Backup。 控制台 CreateFile函数能为控制台输入(CONIN$)创建一个句柄。如果进程存在一个打开的句柄作为继承或复制的结果的结果,它也能为活动的屏幕缓存(CONOUT$)创建一个句柄。正在调用的进程必须属于一个继承控制台或通过AllocConsole函数分配。对控制台句柄来说,如下设置CreateFile参数。 参数 值 lpFileName 使用
34、CONIN$值已定义控制台输入并使用CONOUT$值已控制输出。 CONIN$为控制台的输入缓存获得一个句柄,即使如果SetStdHandle函数重新定义输入句柄的标准。为了的得到输入句柄的标准,使用GetStdHandle函数。 CONOUT$为活动屏幕缓存获得一个句柄,即使SetStdHandle已重定了输出句柄的标准。为了获得这个输出句柄标准,使用GetStdHandle. dwDesiredAccess GENERIC_READ | GENERIC_WRITE为首选项,但是选择二者其一能限制访问。 dwShareMode 如果正在调用的程序继承控制台或一个子程序能
35、够访问控制台,这个参数必须设置为FILE_SHARE_READ | FILE_SHARE_WRITE lpSecurityAttributes 如果你想要控制台被继承,SECURITY ATTRIBUTES的bInheritHandle成员结构体必须为真。 dwCreationDisposition 当使用CreateFile打开控制台时,你需要定义为OPEN_EXISTING。 dwFlagsAndAttributes 忽略。 hTemplateFile 忽略。 以下列表显示了fwdAccess与lpFileName的各种设置的结果。 lpFileName fw
36、dAccess 结果 CON GENERIC_READ 以输入打开控制台 CON GENERIC_WRITE 以输出打开控制台 CON GENERIC_READ GENERIC_WRITE Windows 95/98/Me:致使CreateFile失败;GetLastError返回ERROR_PATH_NOT_FOUND。 Windows NT/2000/XP:致使CreateFile失败;GetLastError返回ERROR_FILE_NOT_FOUND。 目录 一个应用程序不能通过CreateFile创建一个目录;必须调用CreateDirecto
37、ry 或CreateDirectoryEx来创建目录。 Windows NT/2000/XP:你不能在设置FILE_FLAG_BACKUP_SEMANTICS标记时为目录获得一个句柄。一个目录疾病能够被传递给一些函数来代替文件句柄。 一些文件系统,如NTFS,支持个别文件和目录的压缩或加密。在这样一个文件系统的格式化卷标中,一个新的目录继承它父目录的压缩和加密属性。 你不能使用CreateFile函数这只一个目录的压缩类型,使用DeviceIoControl函数来设置它。 当在FAT或FAT32扇区中使用CreateFile来打开一个目录,不能定义MAXIMUM_ALL
38、OWED访问最大值。如果这样设置,访问目录将被禁止。定义GENERIC_READ代替。 实例代码 举例请查阅Creating and Opening Files。 必要条件 Windows NT/2000/XP:包括Windows NT 3.1及以后版本 Windows 95/98/Me: 包括Windows 95及以后版本。 头文件:声明于Winbase.h; 包含Windows.h. 库: 使用Kernel32.lib. 统一字符编码标准: 在Windows NT/2000/XP中适用于统一字符编码标准与ANSI版本.也支持微软统一字符编码标准层。 参见
39、 File I/O Overview, File I/O Functions, ACCESS_MASK, AllocConsole, CloseHandle, ConnectNamedPipe, CreateDirectory, CreateDirectoryEx, CreateNamedPipe, DeviceIOControl, GetDiskFreeSpace, GetOverlappedResult, GetStdHandle, OpenFile, OVERLAPPED, ReadFile, SECURITY_ATTRIBUTES, SetErrorMode, SetStdHandle, Standard Access Rights, TransactNamedPipe, Unique Volume Names, VirtualAlloc, WriteFile






