频繁通过win32api的createfile函数打开文件句柄导致内存泄漏
2017-04-12 16:58
351 查看
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函数
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函数
相关文章推荐
- VS2010中提示无法打开源文件 stdafx.h,.CPP文件中很多类型函数未定义,但是编译通过
- 计数文件打开关闭文件太频繁,导致内存不足
- 打开虚拟机提示内部错误,并且进入虚拟机提示无法获取文件句柄,导致开启虚拟机失败
- 临时文件未清理导致水晶报表周期性打开报表失败
- PhotoFamily导致U盘一插入就马上打开U盘上所有文件目录
- 通过Vc大批量读写excel文件时,若此时打开其它EXCEL文件,则出现批量读写excel文件时发生阻塞?
- linux 文件操作函数 通过例子来解释 父子间文件描述符共享 内存映像图
- 使用与 Win32API 文件通用对话框打开对话框
- 文件的打开 (fopen()函数)
- PHP - Manual手册 - XL. Filesystem 文件系统函数 - is_uploaded_file判断文件是否是通过 HTTP POST 上传的
- CreateFile打开一个文件
- 个人学习代码保存:例10.通过模板创建静态页面的操作文件的一个自定函数
- 使用Windows API函数显示打开文件对话框
- 通过URL从Temporary Internet Files得到本地文件路径的函数
- ABAP文件打开对话框函数
- SharePoint WEB应用程序下的Web.config文件出错导致网站不能打开
- 打开文件夹并且选中指定的文件的通用函数
- 打开文件夹并且选中指定的文件的通用函数
- linux 文件操作函数 通过例子来解释 父子间文件描述符共享 内存映像图
- Eclipse中通过资源管理器打开文件所在文件夹