第6章 Overlapped I/O, 在你身后变戏法 ---Win32 文件操作函数 -2
Win32 之中有三个基本的函数用来执行 I/O,它们是:
i CreateFile()
i ReadFile()
i WriteFile()
没有另外哪一个函数用来关闭文件,只要调用 CloseHandle() 即可。本章对于这些函数将只涵盖其与 overlapped I/O 有关的部分,至于其他和文件 I/O有关的部分,请参考 Win32 Programmer's Reference。
CreateFile() 可以用来打开各式各样的资源,包括(但不限制于):
i 文件(硬盘、软盘、光盘或其他)
i 串行口和并行口(serial and parallel ports)
i Named pipes
i Console(请看第8章)
CreateFile() 的函数原型看起来像这样:
HANDLE CreateFile(
LPCTSTR lpFileName, // 指向文件名称
DWORD dwDesiredAccess, // 存取模式(读或写)
DWORD dwShareMode, // 共享模式(share mode)
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 指向安全属性结构
DWORD dwCreationDisposition, // 如何产生
DWORD dwFlagsAndAttributes, // 文件属性
HANDLE hTemplateFile // 一个临时文件,将拥有全部的属性拷贝
);
其中第6个参数 dwFlagsAndAttributes 是使用 overlapped I/O 的关键。这个参数可以藉由许多个数值组合在一起而完成,其中对于本处讨论最重要的一个数值便是 FILE_FLAG_OVERLAPPED。你可以藉着这个参数,指定使用同 步(传统的)调用,或是使用 overlapped(异步)调用,但不能够两个都指定。换句话说,如果这个标记值设立,那么对该文件的每一个操作都将是overlapped。
一个不常被讨论的 overlapped I/O 性质是,它可以在同一时间读(或写)文件的许多部分。微妙处在于这些操作都使用相同的文件 handle。因此,当你使用 overlapped I/O 时,没有所谓“目前的文件位置”这样的观念。每一次读或写的操作都必须包含其文件位置。
如果你发出许多个 overlapped 请求,那么执行次序无法保证。虽然你在单一磁盘中对文件进行操作时很少会有这样的行为,但如果面对多个磁盘,或不同种类的设备(如网络和磁盘),就常常会看到 I/O 请求完全失去次序。
你将不可能藉由调用 C runtime library 中的 stdio.h 函数而使用overlapped I/O。因此,没有很方便的方法可以实现 overlapped text-based I/O。例如,fgets() 允许你一次读取一行文字,但你不能够使用 fgets()、fprintf() 或任何其他类似的 C runtime 函数来进行 overlapped I/O。
Overlapped I/O 的基本型式是以 ReadFile() 和 WriteFile() 完成的。这个函数的原型如下:
BOOL ReadFile(
HANDLE hFile, // 欲读之文件
LPVOID lpBuffer, // 接收数据之缓冲区
DWORD nNumberOfBytesToRead, // 欲读取的字节个数
LPDWORD lpNumberOfBytesRead, // 实际读取的字节个数的地址
LPOVERLAPPED lpOverlapped // 指针,指向 overlapped info
);
BOOL WriteFile(
HANDLE hFile, // 欲写之文件
LPCVOID lpBuffer, // 储存数据之缓冲区
DWORD nNumberOfBytesToWrite, // 欲写入的字节个数
LPDWORD lpNumberOfBytesWritten, // 实际写入的字节个数的地址
LPOVERLAPPED lpOverlapped // 指针,指向 overlapped info
);
这两个函数很像 C runtime 函数中的 fread() 和 fwrite(),差别在于最后一个参数lpOverlapped 。如果CreateFile() 的第6 个参数被指定为FILE_FLAG_ OVERLAPPED,你就必须在上述的 lpOverlapped 参数中提供一个指针,指向一个 OVERLAPPED 结构。
OVERLAPPED 结构
OVERLAPPED 结构执行两个重要的功能。第一,它像一把钥匙,用以识别每一个目前正在进行的 overlapped 操作。第二,它在你和系统之间提供了一个共享区域,参数可以在该区域中双向传递。
OVERLAPPED 结构看起来像这样:
typedef struct _OVERLAPPED {
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
OVERLAPPED 结构中的成员
表格6-1 描述 OVERLAPPED 结构中的每一个成员。
表格6-1 OVERLAPPED 结构中的成员(栏位)
成员名称 说 明
Internal 通常它被保留。然而当 GetOverlappedResult() 传回 FALSE 并且GetLastError() 并非传回 ERROR_IO_PENDING 时,这个栏位将内含一个视系统而定的状态
InternalHigh 通常它被保留。然而当 GetOverlappedResult() 传回 TRUE 时,这个栏位将内含“被传输数据的长度”
Offset 文件之中开始被读或被写的偏移位置(以字节为单位)。该偏移位置从文件头开始起算。如果目标设备(例如 pipes)并没有支持文件位置,此栏位将被忽略
OffsetHigh 64 位的文件偏移位置中,较高的 32 位。如果目标设备(例如 pipes)并没有支持文件位置,此栏位将被忽略
hEvent 一个手动重置(manual-reset)的 event 对象,当 overlapped I/O 完成时即被激发。ReadFileEx() 和 WriteFileEx() 会忽略这个栏位,彼时它可能被用来传递一个用户自定义的指针
由于 OVERLAPPED 结构的生命期超越 ReadFile() 和 WriteFile() 函数,所以把这个结构放在一个安全的地方是很重要的事情。通常局部变量并不是一个安全的地方,因为它会很快就越过了生存范围(out of scope)。最安全的地方就是 heap。
现在我们有了所有的基础物质,让我们看看如何运用它们。
第6章 Overlapped I/O, 在你身后变戏法 ---Win32 文件操作函数 -2的更多相关文章
- 【阅读笔记】《C程序员 从校园到职场》第六章 常用文件操作函数 (Part 1)
参考链接:https://blog.csdn.net/zhouzhaoxiong1227/article/details/24926023 让你提前认识软件开发(18):C语言中常用的文件操作函数总结 ...
- 第3章 Python基础-文件操作&函数 文件操作 练习题
一.利用b模式,编写一个cp工具,要求如下: 1. 既可以拷贝文本又可以拷贝视频,图片等文件 2. 用户一旦参数错误,打印命令的正确使用方法,如usage: cp source_file target ...
- 第6章 Overlapped I/O, 在你身后变戏法 ---被激发的 Event 对象 -4
以文件 handle 作为激发机制,有一个明显的限制,那就是没办法说出到底是哪一个 overlapped 操作完成了.如果每个文件 handle 只有一个操作等待决定,上述问题其实并不成为问题.但是如 ...
- 第6章 Overlapped I/O, 在你身后变戏法 ---1
这一章描述如何使用 overlapped I/O(也就是 asynchronous I/O).某些时候 overlapped I/O 可以取代多线程的功用.然而,overlapped I/O 加上co ...
- 第6章 Overlapped I/O, 在你身后变戏法 ---被激发的 File Handles -3
最简单的 overlapped I/O 类型,是使用它自己的文件 handle 作为同步机制.首先你以 FILE_FLAG_OVERLAPPED 告诉 Win32 说你不要使用默认的同步 I/O.然后 ...
- [Python学习笔记][第七章Python文件操作]
2016/1/30学习内容 第七章 Python文件操作 文本文件 文本文件存储的是常规字符串,通常每行以换行符'\n'结尾. 二进制文件 二进制文件把对象内容以字节串(bytes)进行存储,无法用笔 ...
- 简学Python第二章__巧学数据结构文件操作
#cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...
- 第十二章 Python文件操作【转】
12.1 open() open()函数作用是打开文件,返回一个文件对象. 用法格式:open(name[, mode[, buffering[,encoding]]]) -> file obj ...
- 第九章 Python文件操作
前一阵子写类相关的内容,把老猿写得心都累了,本来准备继续介绍一些类相关的知识的,如闭包.装饰器.描述符.枚举类.异常等,现在实在不想继续,以后再开章节吧.本章弄点开胃的小菜提提神,介绍Python中文 ...
随机推荐
- The C++ Programming Language 学习笔记 第6章 表达式和语句
1.关于strcpy函数. 书中说c风格的字符串尽量少用,strcpy这样的函数应该也要少用.这里讲这个函数主要是要通过本章课后练习第十题来讲一下前面提及的要点.巩固一下前几章的知识.写了一段,本来感 ...
- vue.js基础知识篇(5):过渡、Method和Vue实例方法
第8章:过渡 1.CSS过渡 2.JavaScript过渡 3.渐进过渡 第9章:method Vue.js的事件一般通过v-on指令配置在HTML中,虽然也可以在js的代码中使用原生的addEven ...
- Eclipse常用快捷键记录
Eclipse简介: Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.幸运的是,Eclipse 附带了一个标准的 ...
- 【NOIP2014】子矩阵
这题如果按暴力做只有一半分,最大时间复杂度为O(C(16,8)*C(16,8)); 很容易算出超时: 我们可以发现如果直接dp会很难想,但是知道选哪几行去dp就很好写状态转移方程: dp[i][j]= ...
- Android持续集成之Jenkins 部署
Android持续集成之Jenkins 部署 [TOC] 0x00安装 准备工作如下: Tomcat8.5下载地址 Jenkins下载链接 1 将下载的jenkins.war包放至tomcat下的we ...
- Spring加载properties文件的属性的值
要使用配置文件的值首先在spring.xml配置加载properties文件 <context:property-placeholder location="classpath:ife ...
- ssh keys管理工具
原文地址:https://rtyan.github.io/%E5%B7%A5%E5%85%B7/2017/09/12/ssh-keys-manager.html 引言 我有两个github账户,一个是 ...
- 新CCIE笔记-路由器的配置
CCIE重修笔记之路由器基本配置与最简单的路由. 路由器与交换机的基本配置命令 全局配置模式下有多种子模式 (华为可以跳跃切换模式) 思科命令行技巧 Tab键补全,也可以直接保留缩写 问号'?'类似l ...
- mysql的压缩特性-需求
需求:最近有个插入量比较大的应用需要上,每天的插入量在1亿左右,同时会有较少的查询,表的单行长度在0.5k,就数据而言每天有近50G数据,由于每天写一张新表,保留30天的数据,一个月下来也要1.5T, ...
- 201521123010 《Java程序设计》第7周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind 2. 书面作业 ①ArrayList代码分析 1.1 解释ArrayList的contains源代码 ...