Jump to content

Compare content of 2 folders


Sebiix3
 Share

Recommended Posts

Hey guys,
I'm once again come to a problem, or I do not quite know how to do it...
I would like to compare 2 folders and their files (+ subfolders) with each other. Would be enough to compare date-modified for each file.
Both folders contain mostly the same files.
I would like to get an array, where all filenames are contained, which differ in the date (date motified) from each other.

E.g. in both folders is the file "test.txt". In folder 1 with the date 12.10.2021 19:25:02, but in folder 2 a newer date. Then the "text.txt" should be in the array because it is newer than in folder 1.
Additionally, I would like to detect "new" files. So those that are already in folder 2, but not in folder 1 get into the array as well.

_FileListArrayToRec seems to be what I need and it also looks subfolders.
Unfortunately I don't know how to do this....

Could someone help me out on this? :)

Thanks in advance!

Link to comment
Share on other sites

I've personally used SMF, but it won't put the files in an array, instead displaying them in a GUI

Alternately, you can start by using some variation of this:

Spoiler
#include <File.au3>

Func Main()

; Get Files of directory1 (DirModifiedTime)
; Get Files of directory2 (DirModifiedTime)

; For each file in Directory1
    ; If found in Directory2 then (_ArraySearch)
        ; If modifiedDate in Dir1 > Dir2
            ; Add to array (_ArrayAdd)
        ; Else
            ; Do nothing?
    ; Else
        ; Do nothing?
; Next

EndFunc

; Returns 1-based 2D array of [<File/Dir>, <ModifiedDate>]
; Requires #include <File.au3>
; See example output with: _ArrayDisplay(DirModifiedTime(@UserProfileDir & "\Documents\", Default, Default, True))
Func DirModifiedTime($sDir, $sFilter = Default, $iFlag = Default, $bReturnPath = Default)
    ; Requires #include <FileConstants.au3>

    ; Get all files
    Local $aFiles = _FileListToArray($sDir, $sFilter, $iFlag, $bReturnPath)
    If @error Then Return SetError(1, 0, False)

    Local $aFileModified[UBound($aFiles)][2]
    $aFileModified[0][0] = $aFiles[0]
    For $i=1 To UBound($aFiles) - 1
        $aFileModified[$i][0] = $aFiles[$i]
        ; Get the last modified date in a string
        $aFileModified[$i][1] = FileGetTime($aFiles[$i], $FT_MODIFIED, $FT_STRING)
    Next

    Return $aFileModified

EndFunc

 

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

That's a tall order. Here is a sample code to get you started:
 

#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>
#include <FileConstants.au3>


$Dir1 = @DesktopDir
$Dir2 = "Directory\To\Folder"

Global $Stamp[0]

Example()

Func Example()
    ;Retrives all file(s) in directory 1 as a full path and sorts them alphabetically.
    Local $FileArray = _FileListToArrayRec($Dir1, "*", $FLTAR_FILES, $FLTAR_NORECUR, $FLTAR_SORT, $FLTAR_FULLPATH)
    ;Uncomment to display the files found.
;~  _ArrayDisplay($FileArray, "Directory 1")
    If @error = 1 Then
        MsgBox($MB_SYSTEMMODAL, "", "Path is invalid.")
        Exit
    ElseIf @error = 4 Then
        MsgBox($MB_SYSTEMMODAL, "", "No file(s) were found.")
        Exit
    EndIf
    For $i = 1 to UBound($FileArray) - 1
        ;Retrieves the last modified date of each element.
        $FileModArray = FileGetTime($FileArray[$i])
        ;Adds them to a new array in the format of 'MM/DD/YY @ ##:##:##'
        _ArrayAdd($Stamp, $FileModArray[1] & "/" & $FileModArray[2] & "/" & $FileModArray[0] & " @ " & $FileModArray[3] & ":" & $FileModArray[4] & ":" & $FileModArray[5], 0)
    Next
    ;Uncomment to display the time stamps of each file.
;~  _ArrayDisplay($Stamp, "Directory 1")
EndFunc

This will return the files and modified dates in the directory of your choosing (currently set to Desktop). From here I would mimic the process for Directory 2 and compare the values of each element. If any differences are found then maintain the integrity of the element in the arrays. Such as:

;Select largest array
If UBound($FileArray1) > UBound($FileArray2) Then
    $length = UBound($FileArray1)
ElseIf UBound($FileArray1) < UBound($FileArray2) Then
    $length = UBound($FileArray2)
Else ;Arrays must be same size
    $length = UBound($FileArray1)
EndIf

;If directories contain the same files and modified dates delete them from array.
    For $i = 1 To $length
    ;Search arrays for similar data, if found delete them.
    $found = _ArraySearch($FileModArray2, $FileModArray1[$i])
    If $found <> -1 Then
        _ArrayDelete($FileArray1, $found)
        _ArrayDelete($FileArray2, $found)
        _ArrayDelete($FileModArray1, $found)
        _ArrayDelete($FileModArray2, $found)
    Else
        ConsoleWrite($Array1[$i] & " not found" & @CRLF)
    EndIf
    Next
EndIf
;The above will need some tweaking to ensure the proper elements are being deleted from $FileArray, perhaps you can just insert the modified dates into the array strings and compare them in whole (C:\Path\to\first\file.txt MM/DD/YYYY @ ##:##:##) and compare just two arrays deleting all similar instances.

Hopefully this gets you started and you can look into some of the logic and functions available to cross the finish line.

Edited by kjpolker
Link to comment
Share on other sites

Since you're really only looking at changes in folder 2 then you should only have to compare the contents of Folder2 against Folder1 (or have I read it wrong), for example:

#include <Array.au3>
#include <File.au3>
Local $sFolder1 = @ScriptDir & "\Folder1"
Local $sFolder2 = @ScriptDir & "\Folder2"
Local $aFolder2 = _FileListToArrayRec($sFolder2, "*", 1, 1, 0, 1)
    If @error Then Exit MsgBox(16, "Error", "No files found")

_ArrayDisplay($aFolder2, "Before")
For $i = $aFolder2[0] To 1 Step - 1
    _CompareTimeStamp($aFolder2[$i])
    If @error Then _ArrayDelete($aFolder2, $i)
Next
$aFolder2[0] = UBound($aFolder2) - 1
_ArrayDisplay($aFolder2, "After")

Func _CompareTimeStamp($_sFilename)
    Local $sFile1 = FileGetTime($sFolder1 & "\" & $_sFilename, 0, 1)
        If @error Then Return SetError(0) ;~ File doesn't exist in Folder1 so leave in array
    Local $sFile2 = FileGetTime($sFolder2 & "\" & $_sFilename, 0, 1)
        If $sFile2 > $sFile1 Then Return SetError(0) ;~ File2 is newer than File1 so leave in array
    Return SetError(1)
EndFunc

 

Link to comment
Share on other sites

Just for your information :

This question was (cross-)posted by the user @Sebiix3 in the German forum as well. A nice solution approach has already been provided there by @Bitnugger , see :

https://autoit.de/thread/87477-2-folder-und-deren-dateien-miteinander-vergleichen/?postID=704897#post704897

 

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

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...