第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中文 ...
随机推荐
- lnmp架构(第一篇)
lnmp 架构 第一篇 nginx 源码安装 nginx的安装包:nginx-1.12.0.tar.gz 建议安装前的修改: 在nginx的解压包中修改文件nginx-1.12.0/src/core/ ...
- Keep in Mind
Do not undermine your worth by comparing yourself with others.It is because we are different and eac ...
- Java架构师系统培训高并发分布式电商实战activemq,netty,nginx,redis dubbo shiro jvm虚拟机视频教程下载
15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 ...
- Spring详解(四)------注解配置IOC、DI
Annotation(注解)是JDK1.5及以后版本引入的.它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查.注解是以‘@注解名’在代码中存在的. 前面讲解 IOC 和 DI 都是通过 ...
- Windows下配置Nginx
一.今天是2017年1月18日.揣着一种也许叫做冲动的心情,决定以后每天都记录和回顾新涉及的技术,巩固已学到的知识,坚持. 二.回归到今天的技术主题,因为之前对于[反向代理]这种技术充满了好奇,借此机 ...
- hdu 6199 沈阳网络赛---gems gems gems(DP)
题目链接 Problem Description Now there are n gems, each of which has its own value. Alice and Bob play a ...
- eclipse如何把多个项目用不同的文件夹分隔开
我们有时候用eclipse时,发现Project Explorer下有非常多的项目,如果大部分不用了还好,我们可以从eclipse上删掉,但是如果还经常会用到的话,删掉了,每次用的时候,还得再重新导入 ...
- RMI,RPC,SOAP对比分析
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp60 1.RMI 使用java的程序员,对于RMI(Remot ...
- node简单配置一台服务器
要想使用nodeJS来搭建服务器,首先需要一个必备的条件:node必须安装,建议为4.0版本及以上: 在node中,为我们封装了好多类,搭建服务器需要的一个类是"http"类. 用 ...
- centos 7 && dotnet core 2.0 && nginx && supervisor
前提 系统:centos 7 目录:/home/wwwroot/www.wuball.com dotnet core 2.0 官方指引 sudo rpm --import https://packag ...