Announcement

Collapse
No announcement yet.

Fast file date/time comparison

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Fast file date/time comparison

    I'm still working on the project of sorting folders into DVD Sized folders (WOrks well - Thanks Michael and crew!) -

    Now while I'm doing that I am going to create a powerpoint that we use for the CD printers we have - including the date of the oldest file and newest file as well as a list of the folders.

    So I touch every file - what's the best way to scan and maintain the oldest and newest file?

    Thinking something along the lines of converting filetime to a systemtime to a variant/double and just comparing....

    Can I just compare by SYSTEMTIME? Ie if st < ft then ....??
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

  • #2
    hi Scott,
    i guess i understand your question.
    being you have your files listing already in text, you might want to have an array that uses User-Defined Data Type (UDT) variables or some other string in a fixed format of your own and place what you want to sort by in a string pattern at the front of your UDT or string, then sort with ARRAY SORT.

    while you are loading that array with a string on the first pass, you may want to use REDIM to that array after some many iterations to increase the size by so many items for future storage, then REDIM the array after all files and info have been read for the final count of the number of files.

    if you stored in the middle of your string the yr,mth,day, and time in military format, it would be easy to copy that string to the beginning of your string where you left room for storing that date and sorting the array will give you the desired effect, kind of like a flat file.

    sorry if i missed your understanding

    but i find this approach very fast without dealing with numbers.
    p purvis

    Comment


    • #3
      Skip using FILETIME, use a QUAD with GetFileTime and then it is easy:

      Code:
      LOCAL qt1 AS QUAD
      LOCAL qt2 AS QUAD
       
      [..]
       
      GetFileTime hFile1, BYVAL %NULL, BYVAL %NULL, BYVAL VARPTR(qt1)
      GetFileTime hFile2, BYVAL %NULL, BYVAL %NULL, BYVAL VARPTR(qt2)
       
      IF (qt1 > q2t) Then ? "File1 is newer"
      SYSTEMTIME should only be used when you need the individual components (ie. for date display).
      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

      Comment


      • #4
        Thanks KEv - that's kinda what i was thinking.

        I will have a time stored though in a variable called "OldestDate"...

        That should be in what format?

        If File1time < OldestDate then OldestDate=File1Time

        That's the game plan..

        Oops I see the answer upon re-reading your reply!

        Tx!
        Scott Turchin
        MCSE, MCP+I
        http://www.tngbbs.com
        ----------------------
        True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

        Comment


        • #5
          You could try the deceptively-named WinAPI function "CompareFileTime" to compare filetimes.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Michael - THANKS! That API ROCKS!!!
            It was perfect for what I needed!!!
            Scott Turchin
            MCSE, MCP+I
            http://www.tngbbs.com
            ----------------------
            True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

            Comment


            • #7
              A definite off-topic message here but am curious.

              I'm running Windows 2000 with IE v6 and WebRoot's SpySweeper. When I
              open this thread, SpySweeper pops up and says that it has caught something
              called VenusSeek ( eros ) trying to install itself and has prevented it from doing
              anything. If I open FireFox v2 then I don't get the warning. But if I click the
              add-on that lets me switch to IE's rendering engine then the warning pops
              up. At this point I figure that there must be a small problem between IE and
              SpySweepers current database. But it has been happening since the thread
              opened and I've gotten 2 updates to SpySweeper's database.

              Anyone else noticed anything? Should I pass this info on to PB?
              Or just stay out of this thread?

              Comment


              • #8
                All,
                The file creation date/time is not what you want here, nor is the file accessed date/time kept up to date. The only thing that matters is the file modification date/time and that is only accurate to the minute. I use the GetFileTime function and convert to system time. Development system is Vista Home Premium. Using PB for Windows 8.04.
                When copying the most up-to-date file I would like to at least mimic the original files creation date and time. I use SetFileTime to make them match.

                Note: Not all file systems can record creation and last access times and not all file systems record them in the same manner. For example, on FAT, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, and access time has a resolution of 1 day (really, the access date). Therefore, the GetFileTime function may not return the same file time information set using SetFileTime. NTFS delays updates to the last access time for a file by up to one hour after the last access.


                jimbo

                Comment


                • #9
                  CompareFileTime works if you are just looking for >, =, <

                  If you want to perform math (difference between to dates for example), I'd recommend using a UNION like so:

                  Code:
                  UNION Quad_Filetime
                     ft AS FILETIME
                     qd AS QUAD
                  END UNION
                  You can then perform math on the .qd and use API functions with the .ft
                  Bernard Ertl
                  InterPlan Systems

                  Comment


                  • #10
                    Code:
                    ' This is the solution I came up with to transfer all Dates and Times during
                    ' file copy.
                    '_________________________________________________________________
                    '
                    '   FUNCTION  CopyFileThread
                    '   by: Jim Fritts
                    '_________________________________________________________________
                    
                    FUNCTION CopyFileThread(BYVAL yyy AS LONG) AS LONG
                    
                      LOCAL ErrNumber AS LONG
                    
                      LOCAL lpfn      AS ASCIIZ*%MAX_PATH
                      LOCAL hFile     AS LONG
                      LOCAL OFS       AS OFSTRUCT
                    
                      LOCAL ftcr      AS FILETIME
                      LOCAL ftmod     AS FILETIME
                      LOCAL ftacc     AS FILETIME
                      LOCAL ft        AS FILETIME
                    
                      SourceFileX      = ""
                      DestinationFileX = ""
                      giWaitForCopy    = 0     '=0 if no files to copy
                    
                        DO
                    
                            WaitHere:
                            IF ProgStat <> 1 THEN GOTO EndRoutine
                    
                            IF giWaitForCopy = 0 THEN
                                DIALOG DOEVENTS 'this cannot be NewEvents because CPU usage will go to 100%
                                SLEEP 10
                                GOTO WaitHere
                            END IF
                    
                    
                            IF PathOK& (FilePath(DestinationFileX)) <> -1 THEN MKDIR FilePath(DestinationFileX)
                    
                            FILECOPY SourceFileX, DestinationFileX
                    
                            SETATTR DestinationFileX, %NORMAL
                    
                            ErrNumber = GetLastError
                            IF ErrNumber <> 0 THEN GOTO EndRoutine
                    
                                'This captures the SourceFiles date and time
                                hFile = FREEFILE
                                lpfn=SourceFileX
                                hFile=OpenFile(lpfn, OFS, %OF_READ OR %OF_SHARE_DENY_NONE)
                                IF GetLastError=0 THEN
                                    GetFileTime hFile, ftcr, ftacc, ftmod
                                    CloseHandle hFile
                                ELSE
                                    GOTO EndRoutine
                                END IF
                    
                                'This changes the DestinationFile date and time to that of the SourceFile
                                hFile = FREEFILE
                                lpfn=DestinationFileX
                                hFile=OpenFile(lpfn, OFS, %OF_WRITE OR %OF_SHARE_DENY_NONE)
                                IF GetLastError=0 THEN
                                    SetFileTime hFile, ftcr, ftacc, ftmod
                                    CloseHandle hFile
                                ELSE
                                    GOTO EndRoutine
                                END IF
                    
                              CALL STOPIT_SOUND
                    
                              SourceFileX      = ""
                              DestinationFileX = ""
                              giWaitForCopy    = 0     '=0 if no files to copy  signals program to continue processing
                    
                        EndRoutine:
                        ' Is main dialog still here?
                        LOOP WHILE ProgStat = 1
                    
                    END FUNCTION

                    Comment


                    • #11
                      I was using this to scan a known directory with no subdirectories - pull out the oldest and newest files so that I could mark the DVD up with the correct dates.

                      Worked like a champ -

                      Code:
                      In a findnextfile loop:
                      
                      Do
                          Select Case Left$(FindData.cFileName,1)
                                 Case ".","_"
                                     Iterate
                          End Select
                          FolderSize = FolderSize + (FindData.nFileSizeHigh * (Quadrafrier)) + FindData.nFileSizeLow
                      
                          'Find the newest and oldest date ranges
                          '--------------------------------------
                          'A value of –1 indicates that the first file time is less than the second file time.
                          'Zero indicates that the first file time is equal to the second file time.
                          'A value of %TRUE indicates that the first file time is greater than the second file time.
                          lResult = CompareFileTime(FindData.ftLastWriteTime, g_OldestDate) 'Do for oldest date
                          If lResult = -1 Then g_OldestDate = FindData.ftLastWriteTime
                          lResult = CompareFileTime(FindData.ftLastWriteTime,g_NewestDate) 'Do for oldest date
                          If lResult = %TRUE Then g_NewestDate = FindData.ftLastWriteTime
                          Incr g_Filecount
                      Loop While FindNextFile(hDir, FindData)

                      Now, this one reads the date/time from himem.sys because it was used for a shareware registration DLL I had used years ago...marks up the new file with the same date/time so that it could not be sorted but last modified date - worked like a champ also.

                      Code:
                      '------------------------------------------------------------------------------------------
                      Function SetFileDateandTime(ccsFileSpec As String,ft As SYSTEMTIME)Export As Long
                      Local hFile     As Long
                      Local Result    As Long
                      Local ccsFileTime  As FILETIME
                      Local fLocTime  As FILETIME
                      
                      hFile = CreateFile(ccsFileSpec + Chr$(0), ByVal %GENERIC_READ Or %GENERIC_WRITE, _
                                          ByVal 0, ByVal %NULL, ByVal %OPEN_ALWAYS, _
                                          ByVal %FILE_ATTRIBUTE_NORMAL, ByVal %NULL)
                      
                      ' convert system date/time to file structure.
                      SystemTimeToFileTime ft, fLocTime
                      ' convert local file time to UTC file time
                      ' setfiletime expects a time that is relative to utc time.
                      LocalFileTimeToFileTime fLocTime, ccsFileTime
                      ' set the file time
                      Result = SetFileTime(ByVal hFile, ByVal %NULL, ByVal %NULL, ccsFileTime)
                      CloseHandle hFile
                      Function = Result
                      End Function
                      '------------------------------------------------------------------------------------------
                      Function GetFileDateandTime(ccsFileSpec As String,ft As SYSTEMTIME)Export As Long
                      Dim fd          As WIN32_FIND_DATA
                      Local hFile     As Long
                      hFile = FindFirstFile(ByVal StrPtr(ccsFileSpec),fd)
                      If IsFalse hFile Then Exit Function
                      ' -- Convert the file time from UTC to local time
                      FileTimeToLocalFileTime fd.ftLastWriteTime, fd.ftLastWriteTime
                      ' -- Convert the file time into a compatible system time
                      FileTimeToSystemTime fd.ftLastWriteTime, ft
                      Function = %TRUE
                      End Function
                      '------------------------------------------------------------------------------------------
                      Scott Turchin
                      MCSE, MCP+I
                      http://www.tngbbs.com
                      ----------------------
                      True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                      Comment


                      • #12
                        We have some 'suspect' code here in both posts 10 and 11

                        Re: Post #10 by Mr. Fritts:
                        That's an old routine, huh?
                        Code:
                         'This captures the SourceFiles date and time
                                  hFile = FREEFILE
                                  lpfn=SourceFileX
                                  hFile=OpenFile(lpfn, OFS, %OF_READ OR %OF_SHARE_DENY_NONE)
                                  IF GetLastError=0 THEN
                                        GetFileTime hFile, ftcr, ftacc, ftmod
                                        CloseHandle hFile
                                  ELSE
                                        GOTO EndRoutine
                                  END IF
                        You don't need FREEFILE here. That's used only to access files using PB statements. In context it hurts nothing, it's simply a useless statement.


                        OpenFile() is a little old....

                        The OpenFile function creates, opens, reopens, or deletes a file.

                        Note This function is provided only for compatibility with 16-bit versions of Windows. New applications should use the CreateFile function.
                        ... and testing GetLasterror() is not the recommended way to check for success on the open:
                        Return Values
                        If the function succeeds, the return value specifies a file handle.

                        If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.
                        Lastly, you don't even need to open the file to get its file time information:

                        With PBWIN 9+/PBCC 5+ you can use the new option provided with the DIR$ function...
                        file$ = DIR$([NEXT] [TO DirDataVar])
                        ('DirDataVar' is a WIN32_FIND_DATA structure. The doc does not explain this, letting you guess at the format of the date members of the "DIRDATA" predefined UDT).

                        If you don't have 9+/5+, you can use the FindFirstFile() function to return a WIN32_FIND_DATA structure. (Don't forget to use DIR$ CLOSE or FindClose() after doing this; see comments re post #11)

                        On your write of the file time, again you use OpenFile(), obsolete. You can use CreateFile() here, too; OR, you can use PB statements to obtain the system file handle required for SetFileTime():
                        Code:
                          hFile = FREEFILE     ' here you DO need a pb handle
                          OPEN    DestinationFileX  FOR BINARY AS hFile    ' any Output-capable mode will do
                          hSys  = FILEATTR (hFile, 2&) 
                          ...
                          SetFileTime   hSys.....
                          CLOSE   hFile

                        In Post # 11 by Mr. Turchin we have this function...
                        Code:
                        Function GetFileDateandTime(ccsFileSpec As String,ft As SYSTEMTIME)Export As Long
                        Dim fd          As WIN32_FIND_DATA
                        Local hFile     As Long
                           hFile = FindFirstFile(ByVal StrPtr(ccsFileSpec),fd)
                        [b] If IsFalse hFile Then Exit Function  [/b]
                        ' -- Convert the file time from UTC to local time
                           FileTimeToLocalFileTime fd.ftLastWriteTime, fd.ftLastWriteTime
                           ' -- Convert the file time into a compatible system time
                           FileTimeToSystemTime fd.ftLastWriteTime, ft
                           Function = %TRUE
                        End Function
                        FindFirstFile() does not return an ISFALSE/ISTRUE-testable value.. it returns a search handle on success, or %INVALID_HANDLE_VALUE (0xFFFFFFFF) on failure.


                        Also, if FindFirstFile() succeeds, you need a FindClose() call against hFile in this procedure. Otherwise that handle remains open and you won't be able to remove or rename the folder in which it is located (someone had this exact problem here once). (The search handle obtained is to the folder).


                        MCM
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment

                        Working...
                        X