Avatar billede ladyhawke Novice
19. juni 2002 - 12:51 Der er 9 kommentarer og
2 løsninger

gennemsøg directory incl. sub directories

Hvordan gennemløber jeg alle filerne i et directory inklusive sub directories for at finde alle flier med en bestemt extension?

(Jeg bruger Visual C++)
Avatar billede borrisholt Novice
19. juni 2002 - 12:55 #1
prøv den her :

#include <direct.h>  // _chdir
#include <io.h>          // _findfirst, _findnext, _finddata_t, _A_SUBDIR
#include <mbstring.h> // _mbsrchr , _strupr
#include <stdio.h>    // prinf
#include <windows.h>  // MAX_PATH
#include <time.h>

union TTimeStamp
{
    __int64 Whole;
    struct
    {
        int Lo;
        int Hi;
    }Other;
};

__int64 GetTimeStamp()
{
  TTimeStamp TimeStamp;
    __asm
    {
      _emit 0x0f
      _emit 0x31
      mov TimeStamp.Other.Lo, eax
      mov TimeStamp.Other.Hi, edx
    }
    return TimeStamp.Whole;
}


double GetCpuSpeed()
{
  const DelayTime = 500;

  int TimerLo, TimerHi;

  int PriorityClass = GetPriorityClass( GetCurrentProcess() );
  int Priority      = GetThreadPriority( GetCurrentThread() );
  SetPriorityClass(GetCurrentProcess() , REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread() , THREAD_PRIORITY_TIME_CRITICAL);

  SleepEx(10, false);

  __asm
  {
    _emit 0x0f
    _emit 0x31
    mov TimerLo, eax
    mov TimerHi, edx
  }

  SleepEx(DelayTime, false);

  __asm
  {
    _emit 0x0f
    _emit 0x31
    sub eax, TimerLo
    sbb edx, TimerHi
    mov TimerLo, eax
    mov TimerHi, edx
  }

  SetThreadPriority(GetCurrentThread() , Priority);
  SetPriorityClass(GetCurrentProcess() , PriorityClass);
 
  return (double) TimerLo / (1000 * DelayTime);   
}


int CheckFile(char *Filename)
{
    int succes=(int) strstr(Filename, "BC5");
    succes += (int) strstr(Filename, "Visual");
    return !succes;
    char Buffer[MAX_PATH]; // Buffer used for containing the line just read
//    int succes=0; // Succes flag
    FILE *file = fopen(Filename, "rt"); // Open the founded file in read + text mode
    while ( fgets(Buffer, MAX_PATH, file) ) // While NOT eof(file) read the next line in to Buffer
    {
        _strupr(Buffer); // Convert Buffer to upcases
        if (succes) break;       
    }
  fclose(file); // Close the file
  return succes;
}

static void Again( )

  struct _finddata_t SearchRec ;  // Struct used for retriving the file informations 
  char Buffer [ MAX_PATH ];      // Buffer used for retriving the full file path
  char NewBuffer [ MAX_PATH ];    // Buffer used for the path and anme of the destinatio file
  long hFile;                      // File Handle
  int  res;                            // Succes flag used for searching   
  bool result = false;

  res = ( ( hFile = _findfirst( "*.cpp" , &SearchRec ) ) == -1 );  // SearchMasks are case-insensitive

  /*
  **  If we did'nt find any files, hFile becomes = -1, and succes flag becomes 1.
  **  Else hFile contains a handle to the file. And res = 0.
  */

  while ( res == 0 )
    {
      if  (! ( SearchRec.attrib & _A_SUBDIR ))  // Is this a file ? And is this a valid filename ?       
      {   
            GetFullPathName( SearchRec.name , sizeof( Buffer ), Buffer, NULL );

            if ( CheckFile(Buffer) )
            {
                strcpy( NewBuffer, "C:\\JENS\\" );
                strcat( NewBuffer , SearchRec.name ); //Place destination filename in NewBuffer
            //    CopyFile( Buffer, NewBuffer , result ); // returns a bool as a sucess flag
                /*
                ** Result specifies how this operation is to proceed if a file of the same name
                ** as that specified by lpNewFileName already exists. If this parameter is TRUE
                ** and the new file already exists, the function fails. If this parameter is FALSE
                ** and the new file already exists, the function overwrites the existing file and
                ** succeeds.
                */
                printf( "found : %s\ncopied to : %s\n", Buffer, NewBuffer );
            }
      }   
      res = _findnext( hFile, &SearchRec );      // Continue searching in the current directory for files
    }
   
  _findclose( hFile ); // Finish searching. release memory.

  res = ( (hFile = _findfirst( "*.*" , &SearchRec ) ) == -1 );  //Update succes flag and start over searching for directorys
   
  while (res == 0)
    {
      if  ( SearchRec.attrib & _A_SUBDIR  && (int) SearchRec.name[0] != 46 )
         
          /*
          ** Is this a Subdirectory ? And not the pointer to this or the previous directory ?               
          */       
      {         
          GetFullPathName( SearchRec.name , sizeof( Buffer ), Buffer, NULL ); //Retrive the full path for the directory           
          _chdir( Buffer );    // Change to the founded directory
          Again( );            // Continue searching the current directory for Subdirectorys and files.         
          _chdir( ".." );  // Change to the previous directory
        }     
      res = _findnext( hFile, &SearchRec );  // Update succes flag and searching for more directorys
    }
  _findclose( hFile ); // Finish searching. release memory.
}

void FindFiles ()
{   
/*      for( int drive = 2; drive <= 26; )
      if( !_chdrive( drive++ ) ) //_chdrive returns a value of 0 if the working drive is successfully changed
      {
        _chdir ( "\\" ); //Change to the root directory
        Again( );
      }
*/
   
    _chdir ( "C:\\" );
    Again( );
}




int main(int argc, char* argv[])
{   
   
      __int64 Start, Stop;
    double TotalSeconds;
    double CPUSpeed =  GetCpuSpeed() ;
//    FILE *f;
   

    //for(;;)
    {

        Start = GetTimeStamp();
        /*
        int j = 0;

   
        for (int i= 0; i<1000; ++i)
        {
            f= fopen ("test.hest", "w+");
            ++j *=3 %373272323;
            j /=3;
            j *=i % 33;
            fputs( "jghalkgjgakhlagagjlgaf", f );
            fflush(f);
            fclose(f);
           
        }
        */
    _mkdir("C:\\JENS\\");
    FindFiles ();

        Stop = GetTimeStamp();
   
        TotalSeconds = (Stop - Start) / (CPUSpeed * 1e6);
 
        printf("Tid Brugt : %f Sekunder\n", TotalSeconds);
    }
    return 0;
}

Jens B
Avatar billede ladyhawke Novice
19. juni 2002 - 13:22 #2
Det var got nok lidt af en smøre, det skal jeg vist lige kigge lidt på...
Avatar billede borrisholt Novice
19. juni 2002 - 14:42 #3
her er et helt program ...

Jens B
Avatar billede jpk Nybegynder
19. juni 2002 - 17:19 #4
Kaldet:
FileSearch("C:\\", "*.txt");
til understående funktion, vil finde alle filer med extension .txt startende fra C:\
I eksemplet her indsættes de i en liste (m_FileList.AddString), men du kan naturligvis gøre hvad du vil...

void FileSearch(CString strDir, CString strFind, bool bSearchSubDirs)
{
    CFileFind finder;
    BOOL bWorking = finder.FindFile(strDir + strFind);
    while(bWorking)
    {
        bWorking = finder.FindNextFile();
        // Gør hvad du vil med filnavnet!
        // Tilføj det fx til en liste...
        m_FileList.AddString(finder.GetFilePath());
    }

    if(bSearchSubDirs)
    {
        bWorking = finder.FindFile(strDir + "*.*");
        while(bWorking)
        {
            bWorking = finder.FindNextFile();
            if(finder.IsDirectory() && !finder.IsDots())
              FileSearch(finder.GetFilePath() + '\\', strFind);
        }
    }
}
Avatar billede jpk Nybegynder
19. juni 2002 - 17:20 #5
Hovsa, det skal være:
FileSearch("C:\\", "*.txt", true);
Avatar billede jpk Nybegynder
19. juni 2002 - 17:20 #6
Funktionen kræver naturligvis brug af MFC, men du skriver jo at du bruger Visual C++..?
Avatar billede jpk Nybegynder
19. juni 2002 - 18:24 #7
Bruger du ikke MfC, kan du bruge denne funktion istedet...

void FileSearch(string strDir, string strFind, bool bSearchSubDirs)
{
    WIN32_FIND_DATA fd;
    HANDLE hFind = FindFirstFile(string(strDir + strFind).c_str(), &fd);
    if(hFind != INVALID_HANDLE_VALUE)
    {
        do
        {
            m_FileList.AddString(string(strDir + fd.cFileName).c_str());
        }
        while(FindNextFile(hFind, &fd));
    }
   
    if(bSearchSubDirs)
    {
        HANDLE hFind = FindFirstFile(string(strDir + "*.*").c_str(), &fd);
        if(hFind == INVALID_HANDLE_VALUE)
            return;

        do
        {
            if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                string strCmp = (LPCTSTR)&fd.cFileName;
                if((strCmp != ".") && (strCmp != ".."))
                    FileSearch(strDir + fd.cFileName + string("\\"), strFind);
            }
        }
        while(FindNextFile(hFind, &fd));
    }

    FindClose(hFind);
}
Avatar billede ladyhawke Novice
20. juni 2002 - 09:24 #8
jpk>> Det var lige sådan noget jeg ledte efter, der mangler dog også et 'true' i FileSearch(finder.GetFilePath() + '\\', strFind); (i sub dir løkken)

begge>> Begge udgaver er til stor hjælp, så pointene deles :-)
Avatar billede jpk Nybegynder
20. juni 2002 - 12:37 #9
Du har helt ret ang. den manglende parameter, det skyldes at jeg selv har implementeret funktionen i en klasse og definitionen er således:
void ClassName::FileSearch(CString strDir, CString strFind, bool bSearchSubDirs=true);
Altså bSearchSubDirs er default true, hvis argumentet ikke gives...
Avatar billede ladyhawke Novice
20. juni 2002 - 12:51 #10
jpk>> tak for oplysningen, jeg vidste ikke at det var sådan man gjorde :-)
Avatar billede jpk Nybegynder
20. juni 2002 - 13:32 #11
Det var faktisk lidt vrøvl...
Det skal naturligvis se sådan ud:

class ClassName
{
public:
  void FileSearch(CString strDir, CString strFind, bool bSearchSubDirs=true);
}

og i implementationen:

void ClassName::FileSearch(CString strDir, CString strFind, bool bSearchSubDirs)
{
  ...
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester