ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:30.72KB ,
资源ID:4576123      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4576123.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Windows核心编程之文件操作.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Windows核心编程之文件操作.docx

1、Windows核心编程之文件操作5.1 磁盘文件的打开和关闭 本节主要讲述磁盘文件的打开和创建,在最后讲述一些对目录的操作。 在Win32下传统的ANSI C函数依然可以用来对函数进行操作,例如:fopen fread fwrite fclose,但M$推荐使用CreateFile,CreateFile函数的用途很多(我最开始时候被这个函数的多用途吓住了),可以打开和创建下面的设备文件: Consoles Communications resources Directories (只能打开) Files Mailslots Pipes 关于管道的创建和打开已经在上章4.5节讲过了,本章主要讲如

2、何对磁盘文件的打开和创建操作。 HANDLE CreateFile( LPCTSTR lpFileName, / file name DWORD dwDesiredAccess, / access mode DWORD dwShareMode, / share mode LPSECURITY_ATTRIBUTES lpSecurityAttributes, / SD DWORD dwCreationDisposition, / how to create DWORD dwFlagsAndAttributes, / file attributes HANDLE hTemplateFile / h

3、andle to template file);文件名 lpFileName:文件名的最大长度为MAX_PATH,文件可以为UNC,例如:serverfile_name可以指明网络上其他主机上的文件。存取方法 dwDesiredAccess:可以通过指定参数表明打开文件读还是写,GENERIC_READ|GENERIC_WRITE表示一个文件进行读写。DELETE表示删除文件。共享属性 dwShareMode:表明文件打开后是否允许文件以某种存取方式(通过指定参数dwDesiredAccess的值)再次被打开, 0 不允许文件再被打开 FILE_SHARE_DELETE 允许其他进程在以后打开

4、文件进行删除 FILE_SHARE_READ 允许其他进程在以后打开文件进行读 FILE_SHARE_WRITE 允许其他进程在以后打开文件进行写 安全描述 lpSecurityAttributes:通过指定安全描述参数可以指定返回的句柄是否可以被子进程继承,如果设置为NULL则表明无法被继承。 typedef struct _SECURITY_ATTRIBUTES DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES; 在结构中设置

5、nLength = sizeof(SECURITY_ATTRIBUTES),lpSecurityDescriptor = NULL,bInheritHandle = TRUE就可以使子进程能够集成句柄。 dwCreationDisposition用来设置文件在存在或不存在时系统采用的方法,可能的取值为: CREATE_NEW:创建新文件,当文件已经存在时函数会返回失败 CREATE_ALWAYS:无论文件是否存在都创建新文件并且清楚原文件的所有属性 OPEN_EXISTING:打开存在的文件,当文件不存在时函数会返回失败 OPEN_ALWAYS:打开文件,当文件已经存在时函数会创建新文件 TR

6、UNCATE_EXISTING:打开文件并将文件截断为零,当文件不存在时函数会返回失败 文件属性和参数 dwFlagsAndAttributes:通过这个参数来指定创建的文件属性和打开文件时的参数,文件属性可以是下面这些值的合并: FILE_ATTRIBUTE_NORMAL 普通文件,设置这个属性时其他属性都不会生效 FILE_ATTRIBUTE_ARCHIVE 归档文件 FILE_ATTRIBUTE_HIDDEN 隐藏文件 FILE_ATTRIBUTE_READONLY 只读文件 FILE_ATTRIBUTE_SYSTEM 系统文件 FILE_ATTRIBUTE_TEMPORARY 临时文件

7、 。 此外该参数还会指定文件操作的标记,可用的标记有下面这些: FILE_FLAG_WRITE_THROUGH 使用WriteThrough模式,系统不会对文件使用缓存,文件的改变马上会被写入到磁盘 FILE_FLAG_OVERLAPPED 使用异步文件操作模式 Win9X不支持异步操作 FILE_FLAG_DELETE_ON_CLOSE 文件被关闭后立即删除文件 FILE_FLAG_RANDOM_ACCESS 说明对文件进行随机读写操作,用于暗示操作系统对该文件的缓存使用进行优化 文件模板 hTemplateFile:当指定文件模板的句柄时该文件模板的所有属性会被复制到当前创建的文件。 Cr

8、eateFile和ANSI C函数中fopen的比较: 操作fopenCreateFile打开读fopen(a.txt,r)CreateFile(a.txt,GENERIC_READ,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)打开写并创建fopen(a.txt,w)CreateFile(a.txt,GENERIC_WRITE,0,NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)打开读写fopen(a.txt,r+)CreateFile(a.txt,GENERIC_WRITE|GENERIC_R

9、EAD,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)打开读写并创建fopen(a.txt,w+)CreateFile(a.txt,GENERIC_WRITE|GENERIC_READ,0,NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)如果文件打开成功则返回文件句柄,否则返回INVALID_HANDLE_VALUE。通过GetLastError来获取错误信息。 文件的关闭很简单,只需要用CloseHandle就可以关闭文件,当文件被关闭时所有缓存内数据都会被写入到磁盘。 文件的删除可以使用下面的函

10、数,并指明文件名 BOOL DeleteFile( LPCTSTR lpFileName / file name);对于目录的创建可以使用: BOOL CreateDirectory( LPCTSTR lpPathName, / directory name LPSECURITY_ATTRIBUTES lpSecurityAttributes / 安全描述 通常情况下设置为NULL);BOOL CreateDirectoryEx( LPCTSTR lpTemplateDirectory, / template directory LPCTSTR lpNewDirectory, / direct

11、ory name LPSECURITY_ATTRIBUTES lpSecurityAttributes / SD);后一个函数可以创建一个和现有目录具有相同属性的新目录。 如果要删除一个存在的目录可以使用 BOOL RemoveDirectory( LPCTSTR lpPathName / directory name);上面这些函数的返回值都是BOOL类型,可以通过返回值判断是否执行成功。如果失败可以通过GetLastError得到错误信息5.2 磁盘文件的正常读写与异步读写 在Win32系统下文件可以支持平常的同步读写和异步读写(但在Win9X下,Win32系统不支持磁盘文件的异步读写)。

12、本节在后面部分将会介绍文件的异步读写,最后一段内容将向大家讲解一下文件的区域加锁。 在Win32系统中支持64位长度的文件,所以在很多文件操作函数中需要两个DWORD参数来表示文件长度,一个DWORD用来表示低32位,另一个用来表示高32位。 文件的读写进行在文件被正确打开后,但请确认在打开文件时设置了正确的读写标记。在Win32的文件操作中没有了以前类似与以前ANSI C中的fputs fgets fprintf fscanf等函数,只有类似于fread和fwrite的ReadFile和WriteFile函数。 ReadFile用于文件读,函数原型为: BOOL ReadFile( HAND

13、LE hFile, / handle to file LPVOID lpBuffer, / data buffer DWORD nNumberOfBytesToRead, / number of bytes to read LPDWORD lpNumberOfBytesRead, / number of bytes read LPOVERLAPPED lpOverlapped / overlapped buffer);其中各项参数的含义为: hFile:文件句柄,为CreateFile时返回的句柄 lpBuffer:保存读入的数据的指针 nNumberOfBytesToRead:指定需要读入的

14、字节数 lpNumberOfBytesRead:返回实际读入的字节数 lpOverlapped:在文件异步读写时使用的数据,在同步读写中全部都设置为NULL,在Win9X中只支持对串口的异步操作。 如果返回值为FALSE并且读入的字节数也返回为0,则表示文件到达了末尾。 WriteFile用于文件写,函数原型为:BOOL WriteFile( HANDLE hFile, / handle to file LPCVOID lpBuffer, / data buffer DWORD nNumberOfBytesToWrite, / number of bytes to write LPDWORD

15、lpNumberOfBytesWritten, / number of bytes written LPOVERLAPPED lpOverlapped / overlapped buffer);参数的含义和ReadFile类似。 如果需要移动文件指针到相关位置(和文件读写不同,这个函数没有异步版本),使用 DWORD SetFilePointer( HANDLE hFile, / handle to file LONG lDistanceToMove, / bytes to move pointer PLONG lpDistanceToMoveHigh, / bytes to move poi

16、nter DWORD dwMoveMethod / starting point);其中各项参数的含义为: hFile:文件句柄,为CreateFile时返回的句柄 lpBuffer:保存读入的数据的指针 lDistanceToMove:移动的字节数低DWORD lpDistanceToMoveHigh:移动的字节数高DWORD,为了支持64位(2的64次方字节)长度的大文件,而用来指定64字节的高32位,如果文件大小只需要32位就可以表示,则设置为NULL ldwMoveMethod:移动方法,可以选择下面的值。FILE_BEGIN 从文件开始处开始移动FILE_CURRENT 从文件开始除

17、开始移动FILE_END 从文件末尾开始移动 函数返回值和参数lpDistanceToMoveHigh(当该参数不为NULL时)表明文件指针当前的位置(从文件头到当前的字节数),但当参数lpDistanceToMoveHigh为NULL时如果返回INVALID_SET_FILE_POINTER表明执行失败,当参数lpDistanceToMoveHigh不为NULL时如果返回INVALID_SET_FILE_POINTER还需要判断GetLastError的返回值是否不为NO_ERROR。下面是两种情况下判断错误。 /第一种情况DWORD dwPtr = SetFilePointer (hFil

18、e, lDistance, NULL, FILE_BEGIN) ; if (dwPtr = INVALID_SET_FILE_POINTER) / Test for failure / Obtain the error code. dwError = GetLastError() ; / 处理错误 / . . . / End of error handler /第二种情况dwPtrLow = SetFilePointer (hFile, lDistLow, & lDistHigh, FILE_BEGIN) ; / Test for failureif (dwPtrLow = INVALID_S

19、ET_FILE_POINTER & (dwError = GetLastError() != NO_ERROR ) / 处理错误 / . . . / End of error handler 在Win32中没有提供得到文件当前指针位置的函数,但通过SetFilePointer也可以确定文件指针当前的位置。在MSDN中提供了两个宏来得到当前文件的指针位置: /对32位长度的文件 #define GetFilePointer(hFile) SetFilePointer(hFile, 0, NULL, FILE_CURRENT)/对超过32位长度的文件 #define GetVLFilePointe

20、r(hFile, lpPositionHigh) (*lpPositionHigh = 0, SetFilePointer(hFile, 0, lpPositionHigh, FILE_CURRENT)对了可以通过SetFilePointer来得到文件长度,方法就是从文件位结束处移动0字节,返回值就是文件的长度。 HANDLE hFile = CreateFile(.);/打开文件进行读DWORD dwLen;dwLen = SetFilePointer (hFile, 0, NULL, FILE_END) ; CloseHandle( hFile ) ;当然Win32中也提供了专门的函数来得

21、到文件的大小 BOOL GetFileSizeEx( HANDLE hFile, / handle to file PLARGE_INTEGER lpFileSize / file size);typedef union _LARGE_INTEGER struct DWORD LowPart; LONG HighPart; ; LONGLONG QuadPart; LARGE_INTEGER, *PLARGE_INTEGER; 其中lpFileSize是一个联合数据,用来表明文件的大小。 文件的异步读写主要是用在大文件的读写上,当使用异步读写时,ReadFile和WriteFile会马上返回,

22、并在读写完成时通知应用程序。 要使用异步功能首先需要在打开文件时指定FILE_FLAG_OVERLAPPED作为标记(dwFlagsAndAttributes),在读写文件时可以使用ReadFile/WriteFile或者ReadFileEx/WriteFileEx来进行读写,当调用不同的函数时读写完成后通知应用程序的方法有所不同的,。下面分别介绍这两种方法: 第一种方法,利用ReadFile/WriteFile,这对函数使用事件信号来进行读写完成的通知,由于磁盘读写是一个比较耗费时间的操作,而且现在的磁盘子系统可以在磁盘读写时脱离CPU而单独进行,例如使用DMA方式,所以在磁盘读写时可以进行

23、其他一些操作以充分利用CPU。关于事件信号相关内容请参考4.4节 进程/线程间同步中事件部分内容。并且在文件读写时提供OVERLAPPED数据。 结构定义如下:typedef struct _OVERLAPPED ULONG_PTR Internal; /系统使用 ULONG_PTR InternalHigh; /系统使用 DWORD Offset; / 文件读或写的开始位置低32位,对于命名管道和其他通信设备必须设置为0 DWORD OffsetHigh; / 文件读或写的开始位置高32位,对于命名管道和其他通信设备必须设置为0 HANDLE hEvent; / 事件量,当操作完成时,这个时

24、间会变为有信号状态 OVERLAPPED; /下面的代码演示了文件异步读取/并且比较了同步和异步之间的性能差异void DoDataDeal(BYTE *pbData,int iLen)/对字节进行操作 Sleep(3*1000);/假设每次计算需要2秒钟/下面是使用异步读的示范代码,假设c:templarge_file.dat文件有130MB大小()/每次读入10MB字节,并且对文件中每个字节进行操作,由于可以使用异步操作所以可以在下一次读入数据的同时进行计算void ReadM1(void) HANDLE hFile = CreateFile(c:templarge_file.dat,GE

25、NERIC_READ,0, NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,NULL); if( INVALID_HANDLE_VALUE != hFile ) HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,read_event); BYTE *pbRead = new BYTE1024*1024*10;/10MB字节 BYTE *pbBuf = new BYTE1024*1024*10; DWORD dwRead,dwCount=0; OVERLAPPED overlap;

26、 overlap.Offset = 0; overlap.OffsetHigh =0; overlap.hEvent = hEvent; DWORD dwBegin= GetTickCount();/记录开始时间 ReadFile(hFile,pbRead,1024*1024*10,&dwRead,&overlap); /开始计算 for(int i=1;i13;i+) printf(M1 i=%dn,i); WaitForSingleObject(hEvent,INFINITE);/等待上一次完成 memcpy(pbBuf,pbRead,1024*1024*10); overlap.Offs

27、et = i * (1024*1024*10); overlap.OffsetHigh =0; overlap.hEvent = hEvent; ReadFile(hFile,pbRead,1024*1024*10,&dwRead,&overlap); /在文件进行读的同时进行计算 DoDataDeal(pbBuf,1024*1024*10); WaitForSingleObject(hEvent,INFINITE);/等待最后一次完成 memcpy(pbBuf,pbRead,1024*1024*10); /数据处理 DoDataDeal(pbBuf,1024*1024*10); /结束计算

28、printf(耗时 %dn,GetTickCount()-dwBegin); /操作完成 CloseHandle(hEvent); CloseHandle(hFile); delete pbRead; delete pbBuf; /下面是上面功能的文件同步读版本void ReadM2(void) HANDLE hFile = CreateFile(c:templarge_file.dat,GENERIC_READ,0, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if( INVALID_HANDLE_VALUE != hFile ) DWOR

29、D dwRead,dwCount=0; BYTE *pbRead = new BYTE1024*1024*10;/10MB字节 BYTE *pbBuf = new BYTE1024*1024*10;/10MB字节 DWORD dwBegin= GetTickCount();/记录开始时间 for(int i=0;i13;i+) printf(M2 i=%dn,i); if(!ReadFile(hFile,pbRead,1024*1024*10,&dwRead,NULL) printf(error read); break; memcpy(pbBuf,pbRead,1024*1024*10);

30、/计算 DoDataDeal(pbBuf,1024*1024*10); printf(耗时 %dn,GetTickCount()-dwBegin); /操作完成 CloseHandle(hFile); delete pbRead; delete pbBuf; 在文件的异步读写中,如果ReadFile/WriteFile返回FALSE,则需要通过LastError来进一步确认是否发生错误,例如下面的错误检测代码: bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, &gOverlapped) ; if (!bResult) switch (dwError = GetLastError() case

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1