VC++中用内存映射文件&用CfileFind递归搜索目录

转载 2006年06月25日 11:42:00
VC++中用内存映射文件
粟利民·电脑报

  在软件的开发过程中,有时需要控制一些程序使他们不能同时运行,也就是多个程序间互斥运行(还包括禁止同一程序运行多个实例)。针对这一问题,我们在 Visual C++6.0中利用内存映射文件实现了多个程序间的互斥运行。内存映射文件可以创建一个没有和磁盘文件相联系的内存对象,将文件的信息映射 到一个进程的地址空间上,我们可以访问该文件中的数据,就如同它位于内存中一样。同时,在程序设计中可以给内存映射文件对象起一个名字,这个名字在整个系 统中是唯一的,这个名字可以在多个进程之间共享,通过名字共享能实现进行信息交换,进而实现多个程序间的互斥运行。 
在讲述具体的编程方法之前,让我们先介绍和内存映射文件操作有关的几个重要的函

CreateFileMapping的函数为指定的文件创建一个文件映射对象,该函数的原形如下: 
HANDLE CreateFileMapping(HANDLE hFile,//用于映射的文件句柄 LPSECURITY? ATTRIBUTES FileMappingAttributes,//内存映射文件的安全描述符 DWORD Flprotect,//文件映射对象 的最大长度的高32位 DWORD dwMaximumSizelow,//最大长度的低32位 LPCTSTR IPNAME//指定这个内存映射文件 的名字)

值得注意的是,参数如果是OXFFFFFFFF,将在操作系统虚拟内存页面替换文件中创建文件映射对象,而不是使用磁盘文件,同时必须给出这个映射对象的大小。

NAO VUEWIFFILE函数将文件的视图映射到一个进程地址空间上,返回LPVOID类型的内存指针。通过它,就可以直接访问文件视图中的信息。 
LPVOID MAP VIEWLFFILE(HANDLE HFILEMAPPINGOBUCT,//映射文件对象句柄  DWORD DWDESIREDACCESS,//访问模式 DWORD DWFILEOFFSETHIGH,//文件偏移地址的高32位  DWORD DWFILEOFFSETHIGH,//文件偏移地址的低32位 DWORD DWNUMBEROFBYTESTOMAP//映射视图的大 小)

在Visual c++6.0中我们用默认方式生成基于对话框的应用程序,在程序的初始化阶段,在CwinApp生类的Initln_stance函数的开始处,添加以下代码:

(//创建内存映射文件对象,mu_texRunning是其名字,所有需要互斥运行 //的程序都使用这个名字(这些代码对于需要互斥运行的程序是通用 的)HANDLE hMap=CreateFileMapping((HANDLE)0Xffffffffnull,PAGE_READWRLTE, 0,128,"Mu_texRunning") if(hMap==NULL)//如果创建失败 (AfxMessageBox("创建用于互斥运行的内 存映文件对象失败!”,MB?OK M ICLNSTOP);

return FALSE;//退出此程序)

//如果已经存在这个同名对象,说明已有需要互斥的其他程序运行了

else if(GetLastError( )==ER_ROR_ALREADY_EXISTS)

(LPVOID ipMen=MapViewOFFile(hMap,FILE_MAP_WRITE,0,0,0);

Cstring str=(char*)ipMem;//获得已在运行的程序的描述信息

UnmapViewofFile(lpMem);//解除映射图

CloseHandle(hMap);//关闭此对象

AfxMessageBox(str,MB_ok MB_ICONSTOP);显示有关的描述信息

Return FALSE;//退出此程序)

Else//经过上面的检查,说明这是第一个运行的互斥程序

(LPVOID ip_mem=MapViewofFile(hMap,FILE_MAP_WRITE,0,0,0);

//这里可写入该程序运行的描述信息,上面的错误提示就是这信信息

strcpy((char*)lpMem,"xxx程序正在运行!”);

UnmapViewofFile(lpMem);//解除映射图)

//下面可以继续执行函数INITIN?STANCE原有的代码了

AfxEnableControl_comtainer();

//当程序运行结束了,要记住调用CHANDIE(HMAP)关闭这个对象句柄,//这里可以在Initinstance函数最后returnFALSE之前调用

CloseHandle(hMap);//关闭内存映文件对象句柄 RETURN false;)以上的程序在Visual C++6.中已调试通过。其 他非对话框类型的程序可以在各自的初始化和终止阶段添加类似的代码,只是如果内存映射文件对象的句柄hMap可能在不同函数中使用,那就要将其定义成 CwinApp生类的成员变量或是全局变量了。 



用CfileFind递归搜索目录 
许福  yesky

  我们知道CfileFind未提供直接遍历其子目录的功能,而有时候我们却常常要遍历某一目录下的所有文件及其子目录。如我们要删除一个目录,而这个 目录下又有子目录,因为Windows不允许删除非空的目录,因此我们必须能够遍历一个目录下的所有子目录,这可以通过简单的递归实现. 

  下面让我们从一个简单的例子开始:如何删除某一目录?(假设我们通过DeleteDirectory(LPCTSTR DirName)函数完成这一功能)

  要删除一个目录,我们要完成下面几步:

  1. 删除该目录下的所有文件

  2. 如果该目录中还有子目录我们要递归地调用DeleteDirectory(LPCTSTR DirName)函数,以删除该子目录下的所有文件

  3. 调用RemoveDirectory(LPCTSTR lpPathName)删除该目录

DeleteDirectory(LPCTSTR DirName)函数的完整实现如下:
BOOL DeleteDirectory(LPCTSTR DirName)
{
CFileFind tempFind; file://声明一个CFileFind类变量,以用来搜索
char tempFileFind[200]; file://用于定义搜索格式
sprintf(tempFileFind,"%s//*.*",DirName);
file://匹配格式为*.*,即该目录下的所有文件 

BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);
file://查找第一个文件
while(IsFinded)
{
IsFinded=(BOOL)tempFind.FindNextFile(); file://递归搜索其他的文件 
if(!tempFind.IsDots()) file://如果不是"."目录
{
char foundFileName[200];
strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200));
if(tempFind.IsDirectory()) file://如果是目录,则递归地调用
{ file://DeleteDirectory
char tempDir[200];
sprintf(tempDir,"%s//%s",DirName,foundFileName);
DeleteDirectory(tempDir);
}
else
{ file://如果是文件则直接删除之
char tempFileName[200];
sprintf(tempFileName,"%s//%s",DirName,foundFileName);
DeleteFile(tempFileName);
}
}
}
tempFind.Close();
if(!RemoveDirectory(DirName)) file://删除目录
{
AfxMessageBox("删除目录失败!",MB_OK);
return FALSE;
}
return TRUE;
}
 


  通过上面的例子,详细读者已学会了如何递归遍历某一目录下的所有文件及子目录了。实际上利用这一点可以作出非常有用的工具。下面我给大家举个小例子。

  用VC编写程序的时候,VC会生成一大堆的中间文件,这些中间文件的体积十分庞大,一般比我们编写的代码要大出10倍以上。当我们想要把我们编写的源 代码保留起来,以供以后查阅时,我们不得不手动删除这些中间文件,而有些时候,你想查看以前某个工程的运行结果,于是你编译该工程,经常这样做的话,如果 你不删除VC生成的中间文件,你的硬盘很快就会被一大堆的中间文件塞满。于是我编写了一个VC的中间文件清理工具。其原理非常简单:

  首先,让用户指定一个需要清理的目录,然后我们通过CFileFind递归地遍历该目录,查找目录名为Debug和Release的目录(这是VC默 认的输出目录,如果你更改了缺省设置的话,必须手动删除之),然后调用上面我们编写的DeleteDirectory函数删除之。

  警告:使用该工具时,一定要确保你的工程没有叫Debug或Release的,而且你的有用的目录名也不能是Debug或Release,否则,使用本工具会全部把它们删掉的。

  另外,本工具也能统计源程序的规模(给出整个工程的行数、c文件数、h文件数和cpp文件数及总的文件数目),你可以用它方便地统计出自己源程序的规模。统计源程序规模的原理也是递归地查找某一目录,其原理和上面讲的DeleteDirestory函数是一致的。

  有了该工具你再也不用手动清理自己机子上那一大堆的中间文件了,当你需要把自己的工程目录保存起来,以供以后查阅时,你就可以通过该工具彻底地清理一下中间文件,平时你再也不用去管那些令人讨厌的中间文件了。

VC中用内存映射文件处理大文件

文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MF...
  • zhyi0000
  • zhyi0000
  • 2015年04月26日 23:40
  • 600

VC++中用内存映射文件

转自: http://www.douban.com/note/230996088/-   -----------------------------------------------------...
  • hemeinvyiqiluoben
  • hemeinvyiqiluoben
  • 2013年06月25日 16:39
  • 394

VC++ 根据关键字或者部分文件名查找文件

主要用到的类 CFIleFind,参考资料http://blog.sina.com.cn/s/blog_61053f850100eu09.html 1、CFileFind类的声明文件保存在afx....
  • zhao0210
  • zhao0210
  • 2015年05月27日 15:18
  • 1871

VC读取大文件之创建文件映射及文件写入效率测试

文件太大,没法一次读取到内存进行操作?Windows提供了内存映射API来读取大文件,与普通文件读取相比,内存映射效率比较高。 从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并...
  • mfcing
  • mfcing
  • 2015年02月11日 15:35
  • 4249

grep技巧(-r):在某一目录下递归[所有子目录]查找某一字串:+文件路径

grep技巧(-r):在某一目录下递归[所有子目录]查找某一字串:+文件路径  2011-04-05 12:15:01|  分类:基本命令|  标签:grep 目录 查找  技巧  e...
  • xiaocao9903
  • xiaocao9903
  • 2013年06月14日 19:14
  • 9002

内存映射文件的方式进行进程间通信

项目中有个场景,vb.net需要调用C++处理后的图片。 原来的处理方案是,C++处理图片后,保存图片到磁盘上,VB.NET再从磁盘上进行读取。 现在想对这个方案进行优化。vb端先新建内存映射文件,再...
  • u013162930
  • u013162930
  • 2015年08月13日 10:07
  • 5063

VC下遍历文件夹中的所有文件的几种方法

一、使用::FindFirstFile和::FindNextFile方法 find(char * lpPath) {   char szFind[MAX_PATH];   WIN32_FI...
  • wllmsdn
  • wllmsdn
  • 2014年05月27日 17:38
  • 4517

Win32非递归遍历和搜索文件以及目录算法

非递归遍历搜索的算法核心在于自己用一个堆栈代替函数调用过程中系统建立起来的堆栈。这个搜索算法有以下几个要点: 搜索的顶层目录在进入循环之前进栈 栈元素存储字符串指针,出栈时释放资源 每次循环开始,栈顶...
  • caoshiying
  • caoshiying
  • 2016年08月15日 13:02
  • 1173

Linux下面文件内容到内存区域的映射

利用mmap(建立内存映射) 相关函数 munmap,open 表头文件 #include #include 定义函数 ...
  • u011046042
  • u011046042
  • 2015年11月13日 09:59
  • 2947

递归搜索所有文件目录

依稀记得当时xie
  • hwb_1988
  • hwb_1988
  • 2014年07月26日 11:18
  • 419
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC++中用内存映射文件&用CfileFind递归搜索目录
举报原因:
原因补充:

(最多只允许输入30个字)