频繁通过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> <h5 style="color:red">["+logType+"]"+GetDataTime()+"</h5> <h6 style="color:red">"+logContent+"</h6> "; } else { str= "<hr> <h5 style="color:blue">["+logType+"]"+GetDataTime()+"</h5> <h6 style="color:blue">"+logContent+"</h6> "; } 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> <h5 style="color:red">["+logType+"]"+GetDataTime()+"</h5> <h6 style="color:red">"+logContent+"</h6> "; } else { str= "<hr> <h5 style="color:blue">["+logType+"]"+GetDataTime()+"</h5> <h6 style="color:blue">"+logContent+"</h6> "; } out<<str.c_str(); out.close(); }建议对文件进行读写操作,尽量使用ofstream、ifstream等c++的库。尽量windows操作系统提供的createfile函数
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: bootstrap的treeview使用
- 下一篇:没有了