• 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 安全描述符
      • 如置为NULL , 则无法被子进程继承
    • 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

转载于:https://www.cnblogs.com/bing-z/p/7071443.html

PoEdu - Windows阶段班 【Po学校】Windows编程 Lesson004_003-2 文件操作相关推荐

  1. Java编程那些事儿——文件操作之写文件

    Java编程那些事儿--文件操作之写文件 Java, Java培训, Java基础, Java学习, Java教程 11.3.1.4 写文件 如前所述,将程序内部的数据输出到程序外部的数据源,应该使用 ...

  2. Visual C++编程中的文件操作

    Visual C++编程中的文件操作 作者:燕山大学 聂栋栋 各种关于文件的操作在程序设计中十分常见,如果能对这些操作都了如指掌,就可以根据实际情况找到最佳的解决方案,从而可以在较短的时间内编写出高效 ...

  3. VC++编程中的文件操作API和CFile类

    VC++编程中的文件操作API和CFile类 在VC编程中,操作文件的方法主要有两种:利用API函数和MFC的CFile类.微软在其中封装了文件的一般操作,下面我就介绍一下如何利用这两种方法实现文件操 ...

  4. windows 平台下,运用 Python 进行简单的文件操作需要用到的函数

    获得路径相关信息 获得目录和文件名 os.getenv()获取环境变量  os.putenv()设置环境变量  os.getcwd() 获得当前目录  os.chdir('要设置的当前目录')  os ...

  5. c++ ifstream 文件不结束_C++核心编程 第十二节 文件操作

    前言:程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放.通过文件可以将数据持久化. C++中对文件操作需要包含头文件 ,C++中操作文件有不同的文件打开方式,具体见下表所示. 文件打开方 ...

  6. 【Linux系统编程】Linux文件操作

    00. 目录 文章目录 00. 目录 01. 文件描述符 02. 常用文件IO函数 2.1 open函数 2.2 close函数 2.3 read函数 2.4 write函数 03. 案例实战 04. ...

  7. 【转】matlab与C/C++混合编程——在Windows/Linux上调用Matlab编译的动态库文件

    转自:matlab与C/C++混合编程--在Windows/Linux上调用Matlab编译的动态库文件_sinat_18131557的博客-CSDN博客 date version comments ...

  8. 《精通Windows API-函数、接口、编程实例》——第4章文件系统

    第4章文件系统 4.2 磁盘和驱动器管理 文件系统的基本概念: 包括磁盘分区,卷,目录,文件对象,文件句柄,文件映射 1.磁盘分区: 物理磁盘,逻辑磁盘 2.卷: 也称逻辑驱动器,是NTFS,FAT3 ...

  9. xp下 c语言用什么编程软件,学C语言在windows XP环境下用什么编程软件好??

    DEV-CPP 可以哦 特别简单的 Dev-C++是一个C&C++开发工具,使用 Delphi/Kylix 开发, 它是一款自由软件,遵守GPL协议.它集合了GCC.MinGW等众多自由软件, ...

  10. windows 下实现socket编程_传送文件

    windows 下实现socket编程_传送文件 其实,Windows下的socket编程与Linux下的类似,这里不再赘述! 参考:http://blog.csdn.net/chudongfang2 ...

最新文章

  1. 这样在一个sql里完成更新和插入,只用一次数据库连接,效率提高了
  2. 机器学习基础专题:逻辑回归
  3. linux ping 报错 sendmsg: Operation not permitted
  4. 生成建表脚本up_CreateTable
  5. Android之如何看混淆后的错误日志代码
  6. java 对象复制字段_利用Java反射机制实现对象相同字段的复制
  7. 马化腾不“爱”刘强东了?
  8. 使用pjsip传输已经编码的视频,源码在github
  9. docker删除es数据_docker使用系列之-(6).docker常用命令
  10. 打标工具labelme或者labelimg遇到图片闪退的完美解决方案
  11. 人脸关键点检测——dlib
  12. 集群通信组件tribes之集群的平行通信
  13. win7激活工具使用
  14. ----实现查看历史记录及清除功能的具体过程----
  15. 高德地图加载标注并实现缩放动画
  16. 开发一款游戏需要服务器系统,搭建一个游戏服务器需要什么
  17. java实现单个或多个文件的压缩、解压缩 支持zip、rar等格式
  18. RLS算法到卡尔曼滤波 II
  19. 红米NOTE5 ROOT教程
  20. 用混合编程实现两个LED交替闪烁

热门文章

  1. hive不在同一台机 hue_【Impala篇】---Hue从初始到安装应用
  2. vue 组件 not defined_Vue、Spring Boot开发小而完整的Web前后端分离项目实战10
  3. python变量使用的三个步骤_Python 动态生成多个变量
  4. 页面右下角弹广告案例
  5. 10通信端口感叹号_开源企业级微信小程序实时通信聊天室技术架构演练
  6. error: implicit declaration of function ‘RAND_egd’ [-Werror=implicit-function-declaration]
  7. LINUX下C语言用access()检查文件可读、可写权限
  8. VS2010:把项目由WIN32改为x64
  9. 介绍一些预言性质的梦
  10. 程序员打产品经理事件:做不了的事情,直接推给主管