Jump to content

How to put the newest file's name into a variable?


Recommended Posts

  • 2 weeks later...

Hi,

It seems easier to use _FileListToArrayNew (as in my sig..) (also allows filtering) [i modified this 10 mins after posting; check you have working version if you got it quickly]

Virtually the same speed..

; _GetNewestFileOrig.au3
#include<_FileListToArrayFaster1f.au3>
Local $timerstamp1 = TimerInit(), $path = @ScriptDir, $Recurse1 = 1;,$Recurse1=0
$Oldestfile = _GetNewestFile1($path, 0, $Recurse1, 1)    ; oldest
Local $c = ConsoleWrite("_FileListToArray3 $Oldestfile= " & Round(TimerDiff($timerstamp1)) & "" & @TAB & " msec" & @LF),$timerstamp4 = TimerInit()
$Newestfile = _GetNewestFile1($path, 0, $Recurse1)   ; newest
Local $c = ConsoleWrite("_FileListToArray3 $Newestfile= " & Round(TimerDiff($timerstamp4)) & "" & @TAB & " msec" & @LF)
If Not @error Then
    Local $c = ConsoleWrite("_GetNewestFile $Oldestfile= " & $Oldestfile & @LF)
    Local $c = ConsoleWrite("_GetNewestFile $Newestfile= " & $Newestfile & @LF)
Else
    MsgBox(16, "Error", "Error occured:" & @CRLF & _
            "@error = " & @error & @CRLF & _
            "@extended = " & @extended)
EndIf
; ---------------------------------------
; Function _GetNewestFile1()
;   Call with:    _GetNewestFile($DirPath [, $DateType [, $Recurse] [, $Oldest])
;   Where:    $DirPath is the directory to search
;       $DateType (0ptional) is the type of date to use [from FileGetTime()]:
;         0 = Modified (default)
;         1 = Created
;         2 = Accessed
;       $Recurse (Optional): If non-zero causes the search to be recursive.
;      $Oldest (Optional): If non-zero find oldest file
;   On success returns the full path to the newest file in the directory.
;   On failure returns 0 and sets @error (see code below).
; ---------------------------------------
Func _GetNewestFile1($DirPath, $DateType = 0, $Recurse = 0, $Oldest = 0, $Filter = '*.*')
    Local $ar_Array = _FileListToArray3 ($path,$Filter, 1, $Recurse), $iTimeStamp = FileGetTime($ar_Array[1], $DateType, 1), $sNewest = $ar_Array[1]
    If $Oldest Then
        For $i = 2 To UBound($ar_Array) - 1
            If FileGetTime($ar_Array[$i], $DateType, 1) < $iTimeStamp Then; noldest
                $iTimeStamp = FileGetTime($ar_Array[$i], 0, 1)
                $sNewest = $ar_Array[$i]
            EndIf
        Next
    Else
        For $i = 2 To UBound($ar_Array) - 1; newest
            If FileGetTime($ar_Array[$i], $DateType, 1) > $iTimeStamp Then
                $iTimeStamp = FileGetTime($ar_Array[$i], 0, 1)
                $sNewest = $ar_Array[$i]
            EndIf
        Next
    EndIf
    If $iTimeStamp= 0 Then
        Return SetError(3, 0, 0)
    Else
        Return $sNewest
    EndIf
EndFunc   ;==>_GetNewestFile1
Best, Randall Edited by randallc
Link to comment
Share on other sites

  • 5 months later...

great script!!

how can i change it so that it just looks for a certain type of file (ie: *.zip)

i changed the *.* to *.zip but that didnt work

thanks!

Got interested in that function and made a few... um, modifications:

$path = 'C:\Temp'

$file = _GetNewestFile($path, 1, 1)

If Not @error Then
    MsgBox(0, 'Newest file', $file)
Else
    MsgBox(16, "Error", "Error occured:" & @CRLF & _
            "@error = " & @error & @CRLF & _
            "@extended = " & @extended)
EndIf

; ---------------------------------------
; Function _GetNewestFile()
;   Call with:  _GetNewestFile($DirPath [, $DateType [, $Recurse]])
;   Where:  $DirPath is the directory to search
;           $DateType (0ptional) is the type of date to use [from FileGetTime()]:
;               0 = Modified (default)
;               1 = Created
;               2 = Accessed
;           $Recurse (Optional): If non-zero causes the search to be recursive.
;   On success returns the full path to the newest file in the directory.
;   On failure returns 0 and sets @error (see code below).
; ---------------------------------------
Func _GetNewestFile($DirPath, $DateType = 0, $Recurse = 0)
    Local $Found, $FoundRecurse, $FileTime
    Local $avNewest[2] = [0, ""]; [0] = time, [1] = file
    
    If StringRight($DirPath, 1) <> '\' Then $DirPath &= '\'
    If Not FileExists($DirPath) Then Return SetError(1, 0, 0)
    
    Local $First = FileFindFirstFile($DirPath & '*.*')
    If $First = -1 Or @error Then Return SetError(2, @error, 0)
    
    While 1
        $Found = FileFindNextFile($First)
        If @error Then ExitLoop
        If StringInStr(FileGetAttrib($DirPath & $Found), 'D') Then
            If $Recurse Then
                $FoundRecurse = _GetNewestFile($DirPath & $Found, $DateType, 1)
                If @error Then
                    ContinueLoop
                Else
                    $Found = StringReplace($FoundRecurse, $DirPath, "")
                EndIf
            Else
                ContinueLoop
            EndIf
        EndIf
        $FileTime = FileGetTime($DirPath & $Found, $DateType, 1)
        If $FileTime > $avNewest[0] Then
            $avNewest[0] = $FileTime
            $avNewest[1] = $DirPath & $Found
        EndIf
    WEnd
    
    If $avNewest[0] = 0 Then
        Return SetError(3, 0, 0)
    Else
        Return $avNewest[1]
    EndIf
EndFunc   ;==>_GetNewestFile

Works for me in minimal testing. It now has error handling, can use any of the three timestamps from FileGetTime, and can search recursively through subdirectories. Be carefull with that Recurse option, it can take a long time to search recursively through something like the Windows directory.

Cheers!

:)

P.S. Actually, after some more testing, I can't make it take more than about 3 sec to do the Windows directory, or about 90 sec to do the whole C: drive. Seems to do OK for speed. :)

Edited by gcue
Link to comment
Share on other sites

great script!!

how can i change it so that it just looks for a certain type of file (ie: *.zip)

i changed the *.* to *.zip but that didnt work

thanks!

That's because the recursion would then only use subdirectories that also matched *.zip. I needed to do something like this myself, and it required a different function. Here is _GetNewestFile() rewritten as _FileGetNewest(). There are several changes:

1. Second parameter can be set to return the oldest vice newest (previous value -3)

2. 4th parameter is an optional mask suitable for FileFindFirstFile(): '*.*' by default.

3. Returned value is now an array where [0] = full path to found file, and [1] = time stamp of found file

Enjoy:

#include <Array.au3>; Only for _ArrayDisplay()

; Find the newest zip file by date created
$avRET = _FileGetNewest("C:\Downloads", 1, 1, "*.zip")
If @error Then
    MsgBox(16, "Error", "@error = " & @error)
Else
    _ArrayDisplay($avRET, "Results")
EndIf

; Find the oldest zip file by date created
$avRET = _FileGetNewest("C:\Downloads", 1 - 3, 1, "*.zip")
If @error Then
    MsgBox(16, "Error", "@error = " & @error)
Else
    _ArrayDisplay($avRET, "Results")
EndIf


; ---------------------------------------
; Function _FileGetNewest()
;   Call with:  _FileGetNewest($sDirPath [, $iDateType [, $iRecurse [, $sPattern]]])
;   Where:  $sDirPath is the directory to search
;      $iDateType (0ptional) is the type of date to use:
;        -3 = (oldest) Modified
;        -2 = (oldest) Created
;        -1 = (oldest) Accessed
;        0 = Newest Modified (default)
;        1 = Newest Created
;        2 = Newest Accessed
;      $iRecurse (Optional): If non-zero causes the search to be recursive.
;       $sPattern (Optional): Wildcard pattern for matching
;   On success returns a 2-element array where:
;       [0] = the full path to the newest file found
;       [1] = the date/time stamp of the file "YYYYMMDDhhmmss" [from FileGetTime()]
;   On failure returns 0, sets @error and @extended (see code below).
;   Author: PsaltyDS
; ---------------------------------------
Func _FileGetNewest($sDirPath, $iDateType = 0, $iRecurse = 0, $sPattern = '*.*')
    Local $avNewest[2] = ["", 0]; [0] = file path, [1] = time stamp
    Local $flagNewest = True, $iModDateType = $iDateType
    Local $hFirst, $sFound, $iFileTime
    Local $hSubDirs, $sSubdir, $avFoundRecurse

    If StringRight($sDirPath, 1) <> '\' Then $sDirPath &= '\'
    If Not FileExists($sDirPath) Then Return SetError(1, 0, 0)
    
    If $iDateType < -3 Or $iDateType > 2 Then Return SetError(1, 1, 0)
    If $iDateType < 0 Then
        $iModDateType = $iDateType + 3
        $flagNewest = False
    EndIf
    
; Start search for files in this dir
    $hFirst = FileFindFirstFile($sDirPath & $sPattern)
    If ($hFirst <> -1) And (@error = 0) Then
        While 1
            $sFound = FileFindNextFile($hFirst)
            If @error Then ExitLoop
            $iFileTime = FileGetTime($sDirPath & $sFound, $iDateType, 1)
            If ($avNewest[1] = 0) Or _
                    (($flagNewest = True) And ($iFileTime > $avNewest[1])) Or _
                    (($flagNewest = False) And ($iFileTime < $avNewest[1])) Then
                $avNewest[0] = $sDirPath & $sFound
                $avNewest[1] = $iFileTime
            EndIf
        WEnd
    EndIf
    FileClose($hFirst)

; Search subdirectories, if $iRecurse is set
    If $iRecurse Then
        $hSubDirs = FileFindFirstFile($sDirPath & '*.*')
        If ($hSubDirs <> -1) And (@error = 0) Then
            While 1
            ; Start search for subdirectories
                $sSubdir = FileFindNextFile($hSubDirs)
                If @error = 0 Then
                ; Only recurse to directories
                    If StringInStr(FileGetAttrib($sDirPath & $sSubdir), "D") Then
                    ; Search a subdirectory
                        $avFoundRecurse = _FileGetNewest($sDirPath & $sSubdir, $iDateType, $iRecurse, $sPattern)
                        If @error Then
                        ; Nothing found
                            ContinueLoop
                        Else
                        ; Check if newest
                            If $avFoundRecurse[1] > $avNewest[1] Then $avNewest = $avFoundRecurse
                            If ($avNewest[1] = 0) Or _
                                    (($flagNewest = True) And ($avFoundRecurse[1] > $avNewest[1])) Or _
                                    (($flagNewest = False) And ($avFoundRecurse[1] < $avNewest[1])) Then
                                $avNewest = $avFoundRecurse
                            EndIf
                        EndIf
                    EndIf
                Else
                ; Done looking for subdirs
                    ExitLoop
                EndIf
            WEnd
        EndIf
    EndIf

    If $avNewest[1] = 0 Then
        Return SetError(2, 0, 0); None found
    Else
        Return $avNewest
    EndIf
EndFunc  ;==>_FileGetNewest

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

my gosh... it works beeeeauuutifully!!!

i also noticed that the script before just looked at date created... now its looking at date modified..

gorgeous

thank you soo much

Link to comment
Share on other sites

  • 1 year later...
  • 9 months later...

How would I use this to assign the oldest file to a variable? I want to run this in a schedule task to delete the oldest file daily.

No interest in post #26?

There are several changes:

1. Second parameter can be set to return the oldest vice newest (previous value -3)

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Let me clarify. I tried using a msgbox to display the oldest (or newest) file, but the message box is blank. Is this a bug?

As you said, it's an array, and arrays can't be displayed by MsgBox(). Use _ArrayDisplay(), but check @error to ensure it succeeded first. Note how the demo does it:

#include <Array.au3>; Only for _ArrayDisplay()

; Find the newest zip file by date created
$avRET = _FileGetNewest("C:\Downloads", 1, 1, "*.zip")
If @error Then
    MsgBox(16, "Error", "@error = " & @error)
Else
    _ArrayDisplay($avRET, "Results")
EndIf

; Find the oldest zip file by date created
$avRET = _FileGetNewest("C:\Downloads", 1 - 3, 1, "*.zip")
If @error Then
    MsgBox(16, "Error", "@error = " & @error)
Else
    _ArrayDisplay($avRET, "Results")
EndIf

See? Checks @error then displays the result with _ArrayDisplay. If you want the file name by itself, follow it with:

$sFile = $avRET[0]

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...