龙仪的家

导航

<2006年6月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

随笔分类

文章分类

收藏夹

随笔档案

文章档案

统计

我的常用网址

代码库之十四-文件搜索类

一直没有找到单步文件查找方式的代码,所以研究了一下,希望能给大家节省些时间。
一个人的精力是有限的,我不可能完成所有的应用所需的类,如果大家有觉得写的比较好比较完善的类,可以发给我(最好是在VC6下可编译),请注明是否可以发表,如果可以发表我会注明作者,加入代码库系列,如果有需求的也可以给我写信或留言,我会根据情况在适当的时候添加到代码库,谢谢大家的支持.
我的EMAIL : lgtest@sina.com
代码并没有经过严格的测试,希望大家能给挑挑错,大家支持是我的动力!.

////////////////////////////////////////////////////H////////////////////////////////////////////////////////////
#ifndef LGLIB_FINDFILE_H
#define
LGLIB_FINDFILE_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <string>
#include <deque>
using namespace std;
namespace lglib
{

     enum FindType
     {
          Find_ERR = -0x0001,
          Find_End = 0x0000,
          Find_Dot = 0x0001,
          Find_Directory = 0x0002,
          Find_Directory_Close = 0x0004,
          Find_File = 0x0008,
          Find_NULL = 0x0010
     };
     typedef BOOL (* OW_DEF_FUNC )(string findedfile,FindType type,const WIN32_FIND_DATA Data);
 
 
    //Q:为什么不用递归?
     //A:由于递归方式在目录层次较深的情况,会发生堆栈溢出情况,而且对资源的消耗也的确比较大

     //Q:为什么写成单步调用?
     //A:由于某些时候,你可能不需要在很短时间内将文件全部搜索完.
     //比如,将一定目录的超过一定时间的文件删除
     //这个任务可能没有那么紧迫,完全可以慢条斯理的解决,并给其他线程留出更多的时间

     //不使用递归搜索文件,就要自己实现一个先进后出的堆栈
     //not use recursion to search file ,actually to realize a stack of own

     //根据堆栈的内容进行搜索,本类不支持多线程操作,如果一定要支持,请自行修改
     //base on the content of stack to search,this
     //this class not support multithread,if u want's to support ,please modify yourself.

     //Create by 龙仪 at 2005-5-29
     class lg_FindFile
     {
     public:

      lg_FindFile();
      virtual ~lg_FindFile();

      //get the SearchPath that u Assign at The Init Function
      //for example this can be use when FileFind return a Find_ERR
      //and u call this function to tell user witch directory not exist

      string GetSearchDir() const;

      //u must call this function once before u call FileFind Function
      BOOL Init(string FilePath,string FileExt);

      //Find DestFile(include a Directory) function
      //The process Function to process the result as u want
      //if The process Function return FALSE this function would break
      //Param type to assign the type you want's to process
      FindType FileFind(OW_DEF_FUNC process,int32 type);

      //reuse this class on new path and fileExt
      //after call this function u must call Init to set path and fileExt
      void Clear();

     private:
      //this function just run one step
      FindType FindOnStep(string& OutString,WIN32_FIND_DATA& Data);

      // compare the end of n byte between two string witch no case
      // if same return true, or return false
      BOOL CompareNoCase(string S1,string S2,size_t n);

      //if the path is a directory would call this function
      FindType AddDirectory(string path,string & OutString);

      //struct backup in DequeList
      struct FilePacket{
           string CurPath;
           HANDLE hFile;
      };

      //Directory will be Search
      string m_FilePath;

      //file extention will be search
      string m_FileExt;
  
      //flag of Init
      BOOL m_bIsInited;

     protected:
      //deque list of struct FilePacket
      deque<FilePacket> DequeList;
 };
}
#endif
// LGLIB_FINDFILE_H

////////////////////////////////////////////CPP///////////////////////////////////////////////////////////

#include "stdafx.h"
#include "filemon.h"
#include "lg_FindFile.h"
#include "lg_Exception.h"
#include <winbase.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
namespace lglib
{

 lg_FindFile::lg_FindFile() : m_bIsInited(FALSE)
 {

 }

 lg_FindFile::~lg_FindFile()
 {
  Clear();
 }

 void lg_FindFile::Clear()
 {
  m_bIsInited = FALSE;
  int Size = DequeList.size();
  for(int i = 0;i < Size;i++)
  {
   FindClose(DequeList.front().hFile);
   DequeList.pop_front();
  }

  //DequeList.empty();
  Size = DequeList.size();
 }

 string lg_FindFile::GetSearchDir() const
 {
  if(!m_bIsInited)
   throw lg_Exception("lg_FindFile::GetSearchDir()","Not Been Inited",0x00000002);
  return m_FilePath;
 }
 BOOL lg_FindFile::Init(string FilePath,string FileExt)
 {
  if(m_bIsInited)
   return FALSE;
  m_FilePath = FilePath;
  m_FileExt = FileExt;
  m_bIsInited = TRUE;
  return TRUE;
 }
 FindType lg_FindFile::AddDirectory(string path,string &OutString)
 {
  WIN32_FIND_DATA FindData;
  FilePacket pack;
  string Temp = path;
  pack.CurPath = path;
  
  int Pos = Temp.rfind('\\');
  
  if((Pos + 1) != Temp.size() ){
   Temp += "\\*.*";
   pack.CurPath += "\\";
  }else{
   Temp += "*.*";
  }
  
  pack.hFile = FindFirstFile(Temp.c_str(), &FindData);
  
  if(pack.hFile == INVALID_HANDLE_VALUE)
   return Find_ERR;
  
  DequeList.push_front(pack);
  OutString = pack.CurPath;
  return Find_Directory;
 }
 //比较字符串后n位是否相同,忽略大小写
 BOOL lg_FindFile::CompareNoCase(string S1,string S2,size_t n)
 {
  if(S1.size() < n || S2.size() < n)
   return FALSE;
  for(int i = 1 ;i< n + 1;i++)
  {
   if(toupper(S1[S1.size() - i]) != toupper(S2[S2.size() - i]))
    return FALSE;
  }
  return TRUE;
 }
 //单步查找文件
 FindType lg_FindFile::FindOnStep(string& OutString,WIN32_FIND_DATA& Data)
 {
  if(!m_bIsInited)
   throw lg_Exception("lg_FindFile::FindOnStep","Not Been Inited",0x00000001);

  WIN32_FIND_DATA FindData;
  
  if(DequeList.size() == 0)
  {

   return AddDirectory(m_FilePath,OutString);

  }else{

   FilePacket pack;
   pack = DequeList.front();
   
   BOOL Ret = FindNextFile(pack.hFile, &FindData);

   if(!Ret)
   {
    FindClose(pack.hFile);
    OutString = pack.CurPath;
    DequeList.pop_front();

    if(DequeList.size() == 0)
     return Find_End;
    else
     return Find_Directory_Close;
   }
   
   if(strcmp(FindData.cFileName, ".") && strcmp(FindData.cFileName, "..") )
   {
    string PathTemp=pack.CurPath;
    PathTemp+=FindData.cFileName;

    if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
     
     return AddDirectory(PathTemp,OutString);
    }
    else
    {
     //比较扩展名是否相同
     if(CompareNoCase(m_FileExt,"*.*",3)||CompareNoCase(PathTemp,m_FileExt,m_FileExt.size()-1))
     {
      OutString = PathTemp;
      Data = FindData;
      return Find_File;
     }
//     if(CompareNoCase(PathTemp,m_FileExt,m_FileExt.size()-1))
//     {
//      OutString = PathTemp;
//      return Find_File;
//     }
    }
   }else{
    return Find_Dot;
   }
  }
  return Find_NULL;
 }
 //查找给定的类型
 FindType lg_FindFile::FileFind(OW_DEF_FUNC process,int32 type)
 {
  FindType Val = Find_NULL;
  string Temp;
  WIN32_FIND_DATA Data;
  while((Val = FindOnStep(Temp,Data))>Find_End){
   if(Val & type){
    if(!process(Temp,Val,Data))
     break;
   }
  }
  return Val;
 }
}

///////////////////////HOW TO USE///////////////////////////

定义lg_FindFile m_FindFile;
m_FindFile.Init("d:\\查找目录","*.jpg");
BOOL MyProcess(string SrcFileName,FindType type,const WIN32_FIND_DATA Data)
{
 static int32 Counter = 0;
 switch(type)
 {
 case Find_Directory:
  LGTRACE(Output_Console,"查找目录%s",SrcFileName.c_str());
  break;
 case Find_Directory_Close:
  LGTRACE(Output_Console,"关闭目录%s",SrcFileName.c_str());
  break;
 case Find_File:
  CTime t = CTime(Data.ftCreationTime);
  LGTRACE(Output_Console,"创建时间%s",t.Format("%Y年%m月%d日%H时%M分%S秒"));
  LGTRACE(Output_Console,"%s-%ld",SrcFileName.c_str(),++Counter);
  break;
 }
 
 return FALSE
}

void CFileMonDlg::OnSearch()
{
     FindType Val =  m_FindFile.FileFind(MyProcess,Find_File|Find_Directory_Close|Find_Directory);
     if(Val == Find_ERR)
     {
          LGTRACE(Output_Console,"目录[%s]不存在",m_FindFile.GetSearchDir().c_str());
     }
    //继续查找其他目录的其他类型文件
    m_FindFile.Clear();
    m_FindFile.Init("d:\\TESTTEST","*.jpgt");
    m_FindFile.FileFind(MyProcess,Find_File);
    .....
}

posted on 2006-06-02 14:53 龙仪 阅读(1597) 评论(0)  编辑 收藏

评论

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]