十四、Win32 API文件操作

1.   Win32 API就是系统调用,偏向底层,像C\C++中的很多函数,比如malloc还有很多文件操作函数都是用Win32 API实现的;


2.   创建文件映射:

       a. 同样也是将硬盘中的文件映射到内存,但是没有FILE *指针指向这片内存了,而是只能用一个void *指针来代替,由此可以看到Win32 API对类型的敏感级别非常低,更加偏向底层,偏向硬件;

       b. 句柄就是指void *指针,其定义就是typedef void *HANDLE,之所以叫句柄,其表面意思就是指一句句话组成的模块的首地址,至于这些话,可以是一个结构体,也可能是一段函数,可以是任何语句,具体实现什么功能不确定,因此将句柄定义为void *指针;

       c. 使用CreateFile函数将文件映射到内存,并返回内存中文件的句柄(即内存区域首地址);

       d. CreateFile的参数(共有7个):

            *1. const void *,即文件路径名;

            *2. DWORD字节型数据(4字节,表示4字节数据,用法和int类似,即typedef unsigned long DWORD),表示读写模式;

            *3. DWORD,共享模式;

            *4. 指向安全属性的指针,这里先不做研究,使用时该参数传NULL即可;

            *5. DWORD,指明文件的创建方式;

            *6. DWORD,文件的属性,隐藏、系统还是正常等;

            *7. HANDLE,用于复制文件的句柄,再次先不讨论,使用时该参数传NULL即可;

        e. 读写模式:

             i.   这只指明读还是写,而不指明文件如何打开(创建、截断等);

             ii.  如何打开的内容由第5个参数决定,注意和前面所讲的文件操作的区别(之前都是将文件的读写和创建放在一个参数中);

             iii. 三种参数:

                   *1. 0:表示既不能读也不能写,仅仅就这么打开一下,啥事儿都不能干;

                   *2. GENRIC_READ:只能读;

                   *3. GNERIC_WRITE:只能写;

                   *4. 将*2.和*3.连用可以既能读又能写;

        f.  共享模式(四种):

             *1. 0:独占,不共享;

             *2. FILE_SHARE_READ:只共享读;

             *3. FILE_SHARE_WRITE:只共享写;

             *4. FILE_SHARE_DELETE:至共享删除文件;

             *5. 后三种模式可以进行组合;

        g. 创建和打开模式:

             i.   创建模式(两种):

                   *1. CREATE_NEW:如果文件不存在就创建,如果已存在则失败;

                   *2. CREATE_ALWAYS:如果文件不存在就创建,如果已存在就截断并将原有属性清空;

             ii.  打开模式(三种):

                   *1. OPEN_EXISTING:如果文件存在就打开但不截断,如果文件不存在就失败,即只打开存在的文件;

                   *2. OPEN_ALWAYS:如果文件存在就打开,如果文件不存在就使用CREATE_NEW创建;

                   *3. TRUNCATE_EXISTING:必须和OPEN_EXISTING合用,如果文件存在就打开并截断,如果文件不存在就失败;

        h. 文件标记和属性:

             i.  文件属性(五种):

                  *1. 都是以FILE_ATTRIBUTE_作为前缀:

                  *2. ARCHIVE:归档;

                  *3. NORMAL:正常,即无属性设置,该属性只有在单独使用时才有效;

                  *4. HIDDEN:隐藏;

                  *5. READONLY:只读;

                  *6. SYSTEM:表示这是一个系统文件,将受到保护;

             ii. 标记(这里只介绍一种):

                  FILE_FLAG_WRITE_THROUGH:指示系统不经过缓存就将文件读入硬盘;


3.   使用WriteFile写入文件:

       a. 参数也是和之前的Write、Read函数大同小异;

       b. 只不过之前的函数都是将(即C语言的fread和fwrite)文件指针作为最后一个参数,而这里是将文件句柄作为第一个参数;

       c. 第二个参数就是内存缓冲区指针,和之前介绍过的函数的内存缓冲区指针一样,都是const void *类型的;

       d. 第三个参数是想写入的字节数,DWORD类型;

       e. 第四个参数是实际写入的字节数,这个参数将作为一个输出参数,而不是作为函数返回参数,由于API没有引用操作,因此只能传一个DWORD变量指针进去,可以实现函数调用多外部变量的值的修改;

       d. 第五个参数是一个异步结构体指针,这里不做研究,使用时该参数传NULL即可;

       e. 程序示例:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		char pBuf[100];
		memset(pBuf, 0, 100);
		HANDLE hFile = CreateFile("M:\\Test Programs\\VC6.0\\Test.txt",
			GENERIC_WRITE,//只写的方式
			0,//独占
			NULL,//无安全属性
			CREATE_ALWAYS,//如果文件不存在则创建,如果文件已存在就截断并清空原有属性
			FILE_ATTRIBUTE_NORMAL,//属性为正常
			NULL//无文件复制属性
			);
		DWORD dwWrites = 0;//定义一个接受实际写入字节数的计数变量
		for ( int i = 1 ; i <= 20 ; i++ ) {
			
			sprintf(pBuf, "Line %d\r\n", i);
			WriteFile(hFile, pBuf, strlen(pBuf), &dwWrites, NULL);
		}
		CloseHandle(hFile);//注意,是CloseHandle而不是CloseFile,因为接受文件内存映射的是一个普通的句柄
		hFile = NULL;//一旦将内存映射区释放掉就要将指针置空,逢野必空!
	}

	return nRetCode;
}

4.   使用ReadFile读取文件:

       a. ReadFile和WriteFile的参数一模一样,只不过pBuf是void *类型的而已;

       b. 在打开文件后需要用API的GetFileSize函数获取文件的字节数,第一个参数是文件句柄,而第二个参数是一个输出参数,他会将文件字节数(是DWORD类型)的高2位字节中的数据返回,因此传的是一个DWORD的指针,这里我们不需要返回值的高2位字节中的内容,只需要返回文件总字节长度就行了,因此这项传NULL就行了;

       c. 程序示例:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		HANDLE hFile = CreateFile("M:\\Test Programs\\VC6.0\\Test.txt",
			GENERIC_READ,//写模式
			0,//独占
			NULL,//无安全属性
			OPEN_EXISTING,//只打开已存在的文件
			FILE_ATTRIBUTE_NORMAL,//文件属性为正常
			NULL//无文件复制属性
			);
		int iFileLen = GetFileSize(hFile, NULL);//获得文件的大小,其实就是测量内存块的大小
		char *pBuf = new char [iFileLen + 1];
		memset(pBuf, 0, iFileLen + 1);
		DWORD dwReads;//定义一个接受实际读入字节数的计数变量
		ReadFile(hFile, pBuf, iFileLen, &dwReads, NULL);
		printf("%s", pBuf);
		CloseHandle(hFile);//释放文件的内存映射
		hFile = NULL;
		delete [] pBuf;
		pBuf = NULL;
	}

	return nRetCode;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值