频繁通过win32api的createfile函数打开文件句柄导致内存泄漏

1、通过win32的createfile、writefile函数打开写入文件

void WriteLogThread(void* lpParameter)
{
	LPLogData pData = (LPLogData)lpParameter;
	string logContent=pData->logContent;
	string logType=pData->logType;
	//释放传参所分配的堆内存
	//HeapFree(GetProcessHeap(), 0, pData);
	delete pData;

	string strPath="C:\\HttpServerLog";
	WIN32_FIND_DATAA wfd;
	HANDLE hFind = FindFirstFileA(strPath.c_str(),&wfd);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		//目录不存在
		CreateDirectoryA(strPath.c_str(), NULL);
	}
	FindClose(hFind);

	HANDLE hFile;
	string fileName="C:\\HttpServerLog\\HttpServerLog"+GetData()+".html";
	do 
	{
		hFile = CreateFileA(fileName.c_str(),     //创建文件的名称。
			GENERIC_WRITE|GENERIC_READ,          // 写和读文件。
			0,                      // 不共享读写。
			NULL,                   // 缺省安全属性。
			OPEN_ALWAYS,          // 总打开文件,如不存在,则创建
			FILE_ATTRIBUTE_NORMAL, // 一般的文件。      
			NULL); // 模板文件为空。

		//文件被占用时
		if(hFile == INVALID_HANDLE_VALUE)
		{
			Sleep(500);//等待500毫秒
		}
	} while (hFile == INVALID_HANDLE_VALUE);

	//设置写入位置
	LONG lDistance = 0;
	SetFilePointer(hFile, lDistance, NULL, FILE_END);

	//往文件里写数据
	string str= "";

	if(logType=="Error")
	{
		str= "<hr>\r\n<h5 style='color:red'>["+logType+"]"+GetDataTime()+"</h5>\r\n<h6 style='color:red'>"+logContent+"</h6>\r\n";
	}
	else
	{
		str= "<hr>\r\n<h5 style='color:blue'>["+logType+"]"+GetDataTime()+"</h5>\r\n<h6 style='color:blue'>"+logContent+"</h6>\r\n";
	}
	int len = lstrlenA(str.c_str());
	DWORD dwWritenSize = 0;
	BOOL bRet = WriteFile(hFile,str.c_str(),len,&dwWritenSize,NULL);

	//先把写文件缓冲区的数据强制写入磁盘。
	FlushFileBuffers(hFile);
	//关闭文件
	CloseHandle(hFile);
}
因为写文件是开线程写的,故写了个循环用于等待获取文件句柄,当文件被占用时,就会一直循环等等。获取到文件句柄后,再调用writefile执行文件写入。

因为程序有内存泄漏问题,即某些内存没有释放掉,故跟踪代码发现在循环createfile这个函数中会存在内存泄漏,应该是句柄泄漏。

正常打开文件句柄后,通过closehandle函数应该能释放掉文件句柄以及占用的内存。但是测试结果就是不行。

2、最后实在找不到原因,怀疑就是win32自身的问题,迫不得已换一种写法用ofstream来写入文件,需要引用头文件#include <fstream>

void WriteLogThread(void* lpParameter)
{
	LPLogData pData = (LPLogData)lpParameter;
	string logContent=pData->logContent;
	string logType=pData->logType;
	//释放传参所分配的堆内存
	//int a =HeapFree(GetProcessHeap(), 0, pData);
	delete pData;

	string strPath="C:\\HttpServerLog";
	WIN32_FIND_DATAA wfd;
	HANDLE hFind = FindFirstFileA(strPath.c_str(),&wfd);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		//目录不存在
		CreateDirectoryA(strPath.c_str(), NULL);
	}
	FindClose(hFind);

	string fileName="C:\\HttpServerLog\\HttpServerLog"+GetData()+".html";

	//利用ofstream进行写操作
	//输出流,把流输出到存储设备
	//ios::in	为输入(读)而打开文件
	//ios::out	为输出(写)而打开文件
	//ios::ate	初始位置:文件尾
	//ios::app	所有输出附加在文件末尾
	//ios::trunc	如果文件已存在则先删除该文件
	//ios::binary	二进制方式
	ofstream out;
	out.open(fileName.c_str(),ios::out|ios::app);
	while(!out.is_open())
	{
		Sleep(5000);
		out.open(fileName.c_str(),ios::out);
	}

	string str= "";
	if(logType=="Error")
	{
		str= "<hr>\r\n<h5 style='color:red'>["+logType+"]"+GetDataTime()+"</h5>\r\n<h6 style='color:red'>"+logContent+"</h6>\r\n";
	}
	else
	{
		str= "<hr>\r\n<h5 style='color:blue'>["+logType+"]"+GetDataTime()+"</h5>\r\n<h6 style='color:blue'>"+logContent+"</h6>\r\n";
	}

	out<<str.c_str();
	out.close();
}
建议对文件进行读写操作,尽量使用ofstream、ifstream等c++的库。尽量windows操作系统提供的createfile函数


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值