PoEdu - Windows阶段班 【Po学校】Windows编程 Lesson004_003-2 文件操做
-
001_函数的不一样版本
- HANDLE : CreateFile()函数返回一个内核对象的句柄
- WINAPI : 一种调用约定,调用方式。
- _In_ 与 _In_opt_ : 自己没有意义,一个说明宏,来标明这个参数的性质。
- _In_ 说明此参数是“输入型”参数
- _In_Opt_ 说明此参数是“输入指针型”参数
- _Out_ 说明此参数是“输出型”参数
- VS2015中,CreateFile()是一个宏:
WINBASEAPI HANDLE WINAPI CreateFileA(
_In_ LPCSTR lpFileName,
……
);
WINBASEAPI HANDLE WINAPI CreateFileW(
_In_ LPCWSTR lpFileName,
……
);
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE
- windows平台编程,关于字符的处理,须要区分两大阵营:1 宽字符集 与 2 窄字符集
- “宽”与“窄”两种不一样的字节集,会致使类型的不一样; 最初CreateFile函数支持的是窄字节,后来发现窄字节在多国语言环境中,是不够用的,windows的设计者们,把CreateFile函数变成一个宏,这个宏使得CreateFile有了CreateFileA()与 CreateFileW()两个版本。CreateFileA()兼容窄字节,CreateFileW()推广宽字节。
- 实际使用过程当中,形成了不少的不方便 :
- 示例1:
wchar_t *filename = L"d:\\1.txt";
CreateFile(filename,……);
- 看示例代码,此时程序员以宽字节设定 filename,可是当外部变换为“窄”字节集时,CreateFile这个宏,能变换成CreateFileW这个版本,而wchar_t * filename不能自动兼容“窄”字节。因此就出现了“TCHAR”这个宏,而右边也出现了“TEXT()”这个宏。
- TEXT()这个宏,做用是:当环境为UNICODE时,在字符串前面加“L”;不然不加“L”。
- 以上整套处理方案,不能移植到linux上,须要彻底的重写。
-
002_CreateFile参数详解
- 参见下面中文翻译
- 事务型操做:
- 把一个操做分红“读”“写”“修改”“完成”4个部分,中间123任意部分失败,则操做无效,“回滚”到操做进行以前的状态。
- 好比程序安装,能够作成一个“事务型”操做,只有当总体完成,这个事务型操做,才算真正的完成,不然“回滚”至安装以前的状态。
- 只有在同步时,会考虑事务型操做;当异步时,事务型操做是不适用的。
- lpFileName 文件名称
- ANSI版本中MAX_PATH 宏 代替 260;Unicode版本中,没有限制长度。
- dwDesiredAccess 权限:以何种权限打开文件
- 能够多个权限叠加使用
- 如置为0,则设备不具备读和写的权限。好比咱们只要访问一文件的建立时间,不须要对文件读和写时,这个设置就很是的合适。
- dwShareMode 共享模式
- 一系列共享给别人的模式。
- 如置为0,别的程序占用了这个文件,那么没法再次被打开。
- 当访问模式冲突时,有GetLastError返回ERROR_SHARING_VIOLATION
- 内核对象打开以后,须要关闭。不然此项设置的权限一直生效。
- lpSecurityAttributes 安全描述符
- dwCreationDisposition 当文件存在与否时,针对存在与否,展开何种操做
- CREATE_ALWAYS 问题建立一个新文件
- 文件被重写成功时,将last-error code设置为ERROR_ALREADY_EXISTS
- 文件不存在,建立成功时,将last-error code 设置为0。
- CREATE_NEW 仅文件不存在时,才建立一个新文件
- 如文件存在,执行失败,将last-error code设置为ERROR_FILE_EXISTS
- OPEN_ALWAYS 老是打开一个文件
- 文件存在,执行成功,置为ERROR_ALREADY_EXISTS
- 文件不存在,路径名合法且可写时,建立一个新文件,last-error code置为0 。
- OPEN_EXISTING 仅在文件存在时,打开它
- 文件不存在,则置为ERROR_FILE_NOT_FOUND
- TRUNCATE_EXISTING 测试一个文件是否存在
- 仅当文件存在时,才打开一个文件而且,将其大小截取到0字节
- 文件不存在,函数执行失败,last-error code置为ERROR_FILE_NOT_FOUND
- dwFlagsAndAttributes
-
003_CreateFile完成
- dwFlagsAndAttributes 属性与标记位
- 对于文件 FILE_ATTRIBUTE_NORMAL是最经常使用 默认值
- 设置文件的属性值的组合,全部属性值是: FILE_ATTRIBUTE_NORMAL
- FILE_FLAG_BACKUP_SEMANTICS
- FILE_FLAG_NO_BUFFERING
- FILE_FLAG_WRITE_THROUGH
- hTemplateFile 内核相同的对象
- 通常为NULL
- 当不为NULL时,上一参数dwFlagsAndAttributes全部设置无效,将继承此参数,也就是新给出的内核对象,继承此对象的全部Flags.
- 返回值
- 返回文件句柄
- 若是失败,返回last-error code 为 INVALID_HANDLE_VALUE
- 备注 具体查看MSDN 历史问题,疑难问题,在出问题时查看
-
CreateFile中文翻译:
- 函数功能
- CreateFile 函数用于建立或打开一个文件或者 I/O 设备。最常使用的 I/O 设备以下:
- 文件
- 文件流
- 文件夹
- 物理磁盘
- 逻辑磁盘驱动器
- 控制台程序缓冲区
- 磁带
- 通讯资源
- 邮槽
- 管道
- 此函数返回一个指向用于访问来自不一样类型I/O的文件或设备的句柄,其访问权限取决于它所访问的文件、设备和咱们所指定的标记位、属性。
- 为了使之能够处理事务型 I/O,请使用 CreateFileTransacted 函数。
- 函数原型
- 参数解析
- lpFileName
- 1 指定要打开、建立的文件或设备的名字。你能够在名字中使用斜杠(/)或者反斜杠(\)
- 2 在此函数的 ANSI 版本中,名字长度被限制为 MAX_PATH 个字符。为了将此限制扩展到 32767 个宽字符,须要调用此函数的 Unicode 版本,而且在添加在路径名中添加 “\?\” 前缀。获取更多的信息,参见 Naming Files, Paths, and Namespaces
- 3 想获取关于特殊设备的名字,参见 Defining an MS-DOS Device Name
- 4 为了建立一个文件流,须要指定文件名,一个冒号加上流文件的名字。获取更多信息,参见 File Streams
- dwDesiredAccess
- 指定以何种权限打开文件或设备,能够概括为:读访问权、写访问权、读写访问权、非读非写访问权
- 最常使用的值为 GENERIC_READ, GENERIC_WRITE, 或者两者都用(GENERIC_READ | GENERIC_WRITE)。获取更多信息,参见 Generic Access Rights, File Security and Access Rights, File Access Rights Constants 和 ACCESS_MASK
- 若是参数值为 0,那么程序能够在不访问文件或设备状况下,询问某些元数据,如文件、目录或者设备属性。此外,即便 GENERIC_READ 请求,也会被拒绝
- 你没法请求一个与共享模式冲突的访问权限。共享模式是在参数 dwShareMode 中设置的
- 获取更多信息,参见本文备注以及 Creating and Opening Files
- dwShareMode
- 设置文件或者设备的共享模式,包括读、写、读写、删除、所有权限或者以上什么权限都没有(参考下面的表格)。此参数不影响对属性和扩展属性的访问请求
- 若是此参数为 0 且 CreateFile 函数执行成功,那么此文件或设备没法被共享,且在其句柄被关闭前,没法被再次打开。更多信息,参见本文备注。
- 你没法设置一个与访问模式相冲突的共享模式。此时若是 CreateFile 函数执行失败,那么 GetLastError 函数会返回 ERROR_SHARING_VIOLATION
- 为了容许进程去共享一个已经在另外一个进程中打开的文件或句柄,那么可对如下一个或多个取值进行组合,且各取值间须要可互相兼容。更多有关此参数与 dwDesiredAccess 参数的合法取值组合的信息,参见 Creating and Opening Files
- 注意:在句柄被关闭以前,每一个句柄的共享选项都会一直生效,且与进程的运行上下文(process context)无关。
- lpSecurityAttributes
- 指向 SECURITY_ATTRIBUTES 结构体的指针。此结构体拥有两个分开可是相关的数据成员:一个是可选的安全描述符,另外一个是决定返回的句柄是否能够被子进程继承的 Boolean 值
- 此参数能够设置为 NULL
- 若是参数为 NULL,那么 CreateFile 函数返回的句柄没法被任意此进程的子进程所继承,且与返回的句柄所对应的文件或句柄拥有一个默认的安全描述符
- 该结构体的 lpSecurityDescriptor 成员为文件或设备指定一个安全描述符(SECURITY_DESCRIPTOR)。若是此成员取值为 NULL,那么与返回的句柄所对应的文件或句柄拥有一个默认的安全描述符
- 当打开一个已经存在的文件或设备时,CreateFile 函数忽略 lpSecurityDescriptor 成员,可是 bInheritHandle 成员仍然可使用
- 结构体的 bInheritHandle 成员用于设置返回的句柄是否能够被继承
- 更多信息,参见本文备注
- dwCreationDisposition
- 用于设置当文件存在或不存在时,要对文件或设备执行何种操做
- 对于设备来讲,此参数一般设置为 OPEN_EXISTING
- 更多信息,参见本文备注
- 这个参数的值必须为如下值之一,且只能选择一个而不能组合多个:
- dwFlagsAndAttributes
- 文件或设备的属性值和标记位,对于文件来讲,FILE_ATTRIBUTE_NORMAL 是最经常使用的默认值
- 此参数能够是任意文件属性值(FILE_ATTRIBUTE_*)的组合。全部其余的文件属性值会覆盖 FILE_ATTRIBUTE_NORMAL
- 此参数也能够包含任意标记位(FILE_FLAG_*)的组合以控制文件或设备的行为、权限设置和其余目的。此外,还能够与任意 FILE_ATTRIBUTE_* 进行组合
- 这个参数还能够经过指定 SECURITY_SQOS_PRESENT 标记来包含 Security Quality of Service (SQOS) 信息。与SQOS相关的标记位信息见属性与标记位表格下面的表格中
- 注意:当CreateFile 打开一个已存在的文件时,它一般将文件属性和文件标记位组合在一块儿,而且忽略在 dwFlagsAndAttributes 中定义的属性值。详细例子见 Creating and Opening Files
- 如下的属性和标记位可能只适用于文件的打开,而并不是支持全部其余 CreateFile 函数能够打开的设备。想了解更多信息,参见本文备注部分和 Creating and Opening Files。想进一步了解文件属性相关信息,参见 SetFileAttributes 函数。你还能够在 File Attribute Constants 中看到完整的介绍全部文件属性的值和对应描述信息
- hTemplateFile
- 指向一个拥有 GENERIC_READ 访问权限的的模板文件的合法句柄
- 此模板文件为即将建立的文件提供属性和扩展属性
- 参数值能够为 NULL
- 若是打开一个已存在的文件,则 CreateFile 函数忽略这个参数
- 若是打开一个新的被加密文件,此函数从其父目录中继承自由存取控制列表。更多信息,见 File Encryption
欢迎关注本站公众号,获取更多信息