File Utility Routine

I have been assigned a task to check the files in a directory, if the timestamp on those files are 2 weeks old I need to delete them.
The whole program has to go recursively.
(Checking for subdirectories too!!)
Can anyone show me how to acmplsh this task.

Thx and appreciation in adv. for any help....
veselAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

lif081199Commented:
Can you use the Win32 SDK ?
0
veselAuthor Commented:
yes, I am on Win2000 platform using vc++6
0
jkrCommented:
void CheckFiles ( char* pszPath)
{
WIN32_FIND_DATA w32fd;
HANDLE hFind;

hFind = FindFirstFile ( pszPatch, &w32fd);

if ( INVALID_HANDLE_VALUE == hFind)
{
 // error
}

// recurse if directory...
if ( FILE_ATTRIBUTE_DIRECTORY == w32fd.dwFileAttributes)
{
 CheckFiles ( w32fd.cFileName)
}
else
 HandleFile ( &w32fd);

while ( FindNextFile ( hFind, &w32fd))
{
    // recurse if directory...
    if ( FILE_ATTRIBUTE_DIRECTORY == w32fd.dwFileAttributes)
    {
     CheckFiles ( w32fd.cFileName)
    }
    else
      HandleFile ( &w32fd);
}

if ( ERROR_NO_MORE_FILES != GetLastError()))
{
 // error
}
FindClose ( hFind);
}

void HandleFile ( WIN32_FIND_DATA* pw32fd)
{
 // check for file age

 if ( <older than 2 weeks>)
      ::DleteFile ( pw32fd->cFileName);
}

Feel Free to ask if you need more information!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

veselAuthor Commented:
Whats the function to check for files with 2 weeks old??
Thx for that
0
lif081199Commented:
jkr : What about the "." directory ? I think you recursion is going to be into an infinite loop, isn't it ?

0
jkrCommented:
It should be placed in

void HandleFile ( WIN32_FIND_DATA* pw32fd)
{
 // check for file age

 if ( <older than 2 weeks>)
      ::DleteFile ( pw32fd->cFileName);
}

e.g.
void HandleFile ( WIN32_FIND_DATA* pw32fd)
{
            SYSTEMTIME sysTime;

            FILETIME   tTime;

            GetSystemTime ( &sysTime);

            SystemTimeToFileTime ( &sysTime, &tTime);


            // Horrible, disgusting hack!  The two line below basically grabs the
            // contents of a FILETIME structure and store it in a 64 bit integer.
            LONGLONG    tFileTime       = *( LONGLONG *)    &pw32fd->ftCreationTime;
            LONGLONG    tActTime        = *( LONGLONG *)    &tTime;

            DWORD       tFile, tAct;

            DWORD       tTwoWeeks = 1209600; // seconds!

            // The LONGLONGs contain the time in 100 nanosecond intervals (now
            // there's a useful unit of measurement...).  Divide each of them by
            // 10000 to convert into milliseconds, and store the results in a
            // DWORD.  This means that the max time before overflowing is around
            // 4 Million seconds (about 49 days)
            tFile   =   ( DWORD)( tFileTime / 10000);
            tAct   =   ( DWORD)( tTime / 10000);

            if ( (tFile - tAct) > tTwoWeeks)
                 ::DeleteFile ( pw32fd->cFileName);
}
0
veselAuthor Commented:
Yes so I will check for . and .. and skip those finds and follow the rest.
Guys I need the function to check for files 2 weeks old!!

Thx
0
veselAuthor Commented:
JKR you are the guy men U know the heart of api's. As soon as I get that working you get 200 points and always my appreciation....

Thx
PS: In order the program not to check the . and .. I have got an if statement is that ok!!
Coz I don't want the program to go into infinite recursion...
0
jkrCommented:
Ooops, lif is right.

Change the beginning of the function to read

void CheckFiles ( char* pszPath)
{
WIN32_FIND_DATA w32fd;
HANDLE hFind;

      if      (      '.'      ==      * (pszPath +            lstrlen      (      pszPath)      -      1))
                return;
0
veselAuthor Commented:
Dear jkr I having problems in finding the files. If I type in the dirpath as d:\\test\\*.* I can see the files showing up in the variable box during debug
But I specify the path as d:\\test\\ it fails to find the files and program doesn't work
Can U please test the program and send me the updated version..
Thx and lots of appreciations...
0
jkrCommented:
>>But I specify the path as d:\\test\\

That's right, it is the 'default' behaviour of 'FindFirstFile()'...

To remedy this:

void CheckFiles ( char* pszPath)
{
WIN32_FIND_DATA w32fd;
HANDLE hFind;
DWORD dwAtt;
char acPath [ MAX_PATH];

lstrcpy ( acPath, pszPath);

dwAtt = GetFileAttributes ( acPath);

if ( 0xffffffff == dwAtt)
{
 // error ...
}

if ( FILE_ATTRIBUTE_DIRECTORY & dwAtt)
{
    if  (   '\\'    ==  acPath  [   lstrlen (   acPath) -   1])
            lstrcat (   acPath, "*.*");
     else
            lstrcat (   acPath, "\\*.*");

}


hFind = FindFirstFile ( acPath, &w32fd);

// ...

}
0
veselAuthor Commented:
Its also giving me error 206(which means filename is too long) when it suppose to look under subdir and delete the files

Thx again...
0
jkrCommented:
Hmm, that's strange - does this happen at the first recursion or deeper?
0
veselAuthor Commented:
Its not going inside subdirectories!!!
Unable to delete files inside the subdirs

Thx
0
veselAuthor Commented:
First Recursion itself...
0
veselAuthor Commented:
Sorry for the last info, I double checked it right now,it doesn't happens at the first recursion...

Thx
0
jkrCommented:
That sounds better ;-)

Could you check the contents of the path, e.g.

lstrcpy ( acPath, pszPath);

OutputDebugString ( acPath);

dwAtt = GetFileAttributes ( acPath);

if ( 0xffffffff == dwAtt)
{
 // error ...
}

if ( FILE_ATTRIBUTE_DIRECTORY & dwAtt)
{
    if  (   '\\'    ==  acPath  [   lstrlen (   acPath) -   1])
            lstrcat (   acPath, "*.*");
     else
            lstrcat (   acPath, "\\*.*");

}

OutputDebugString ( acPath);
0
jkrCommented:
BTW: Have to head home now (remember, Europe here ;-) but will be 'online' again in approx. 1h...
0
jkrCommented:
Back again - did you check it?
0
veselAuthor Commented:
I have figured the problem, when it looks for subdir it doesn;t sticks the entire path like
c:\Folder\subir to it so its not able to find the files correct path.

Thx
0
veselAuthor Commented:
At the deleteFiles function the value of  pw32fd->cFileName is only the filename(I think it should be the entire path with the filename!)

CheckFiles ( w32fd.cFileName);  this works good when there is no subdir but when there is a subdir the  w32fd.cFileName is subsistuted with the subdir and it just crashes there(I guess again that it should be the entire path with the subdir name)

Thx
0
jkrCommented:
Aaah, found the problem - will post the solution later...
0
jkrCommented:
OK, here's the fix:

void CheckFiles ( char* pszPath,    char*   pszBase)
{
WIN32_FIND_DATA w32fd;
HANDLE hFind;
DWORD dwAtt;
char acPath [ MAX_PATH];
char acBase [ MAX_PATH];

if ( '.' == * (pszPath + lstrlen ( pszPath) - 1))
                return;

if  (   pszBase)
    sprintf (   acPath, "%s\\%s",   pszBase,    pszPath);
else
    lstrcpy ( acPath, pszPath);

lstrcpy ( acBase, acPath);

dwAtt = GetFileAttributes ( acPath);

if ( 0xffffffff == dwAtt)
{
 // error ...
}

if ( FILE_ATTRIBUTE_DIRECTORY & dwAtt)
{
    if  (   '\\'    ==  acPath  [   lstrlen (   acPath) -   1])
            lstrcat (   acPath, "*.*");
     else
            lstrcat (   acPath, "\\*.*");
}
 


hFind = FindFirstFile ( acPath, &w32fd);

if ( INVALID_HANDLE_VALUE == hFind)
{
 // error

 return;
}

// recurse if directory...
if ( FILE_ATTRIBUTE_DIRECTORY == w32fd.dwFileAttributes)
{
     CheckFiles ( w32fd.cFileName,  acBase);
}
else
 HandleFile ( &w32fd);

while ( FindNextFile ( hFind, &w32fd))
{
    // recurse if directory...
    if ( FILE_ATTRIBUTE_DIRECTORY == w32fd.dwFileAttributes)
    {
     CheckFiles ( w32fd.cFileName,  acBase);
    }
    else
      HandleFile ( &w32fd);
}

if ( ERROR_NO_MORE_FILES != GetLastError())
{
 // error
}
FindClose ( hFind);
}
0
jkrCommented:
Ooops, BTW:

Call it like

CheckFiles ( "d:\\test\\", NULL);
0
veselAuthor Commented:
Dear jkr I have fixed that. The only problem that is coming right now is the files age.
I think the program is not able to delete the files that are 2 weeks old.
It just deletes all the files.
Can U please look into that...
I am also working on that..

Thanking you...
0
jkrCommented:
Sorry, again my fault...

Two things:

    tFileTime       = *( LONGLONG *)    &pw32fd->ftLastWriteTime;

and

    if ( (tAct - tFile) > tTwoWeeks)
         ::DeleteFile ( pw32fd->cFileName);



because 'if ( (tFile - tAct) > tTwoWeeks)' is simply false...

About the difference of the 'creation time' and the 'last write time' - it's up to you what you need...
0
veselAuthor Commented:
I figured that out heres the modification i have done
 tFile   =   ( DWORD)( tFileTime / 100000000000);      // Getting time in secs
    tAct   =   ( DWORD)(tActTime/ 100000000000);            // Gett

Thx
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.