Hier noch eine Demo mit Ausgabe des Copy-Befehls:
AutoIt
;-- TIME_STAMP 2021-10-13 07:33:49
Opt('MustDeclareVars', 1)
#include <File.au3>
; Pfade ohne abschließenden Slash!
;~ Global $g_sPath1 = 'm:\Temp\Dir1', $g_sPath2 = 'm:\Temp\Dir2'
Global $g_sPath1 = @ScriptDir & '\Temp\Dir1', $g_sPath2 = @ScriptDir & '\Temp\Dir2'
Global $g_sSlash1 = StringInStr($g_sPath1, '\') ? '\' : '/'
Global $g_sSlash2 = StringInStr($g_sPath2, '\') ? '\' : '/'
Global $g_sSource, $g_sDestination
Global $g_aResult = _CompareDirs($g_sPath1, $g_sPath2)
ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & " var: $g_aResult --> " & $g_aResult & @LF & "!@ " & @TAB & "#Error: " & @error & @TAB & "#Extended: " & @extended & @LF)
If UBound($g_aResult) Then
ConsoleWrite(_ArrayToString($g_aResult, ' | ') & @CRLF & @CRLF)
_Copy2D($g_aResult)
_ArrayDisplay($g_aResult, '_CompareDirs("' & $g_sPath1 & '", "' & $g_sPath2 & '")', '', 0, Default, 'Name|Größe|Datum|<=>|Datum|Größe|Name')
EndIf
Func _Copy2D($g_aResult)
If Not UBound($g_aResult) Then Return SetError(1)
For $i = 0 To UBound($g_aResult) - 1 Step 1
Switch $g_aResult[$i][3]
Case '==' ; Files are identical
ContinueLoop
Case '->' ; Copy from $g_sPath1 to $g_sPath2
$g_sDestination = $g_aResult[$i][6] ? $g_aResult[$i][6] : StringReplace($g_aResult[$i][0], $g_sPath1, $g_sPath2)
ConsoleWrite('- -> FileCopy("' & $g_aResult[$i][0] & '", "' & $g_sDestination & '", $FC_OVERWRITE + $FC_CREATEPATH)' & @CRLF)
Case '<-' ; Copy from $g_sPath2 to $g_sPath1
$g_sSource = $g_aResult[$i][0] ? $g_aResult[$i][0] : StringReplace($g_aResult[$i][6], $g_sPath2, $g_sPath1)
ConsoleWrite('! <- FileCopy("' & $g_aResult[$i][6] & '", "' & $g_sSource & '", $FC_OVERWRITE + $FC_CREATEPATH)' & @CRLF)
EndSwitch
Next
EndFunc ;==>_Copy2D
Func _CompareDirs($_sPath1, $_sPath2)
Switch False
Case StringInStr(FileGetAttrib($_sPath1), 'D') ; ist kein Verzeichnis!
Return SetError(1, 1)
Case StringInStr(FileGetAttrib($_sPath2), 'D') ; ist kein Verzeichnis!
Return SetError(1, 2)
Case $_sPath1 <> $_sPath2 ; Verzeichnis sind indentisch!
Return SetError(1, 3)
EndSwitch
Local $sSlash1 = StringInStr($_sPath1, '\') ? '\' : '/'
Local $sSlash2 = StringInStr($_sPath2, '\') ? '\' : '/'
; _FileListToArrayRec ( $sFilePath [, $sMask = "*" [, $iReturn = $FLTAR_FILESFOLDERS [, $iRecur = $FLTAR_NORECUR [, $iSort = $FLTAR_NOSORT [, $iReturnPath = $FLTAR_RELPATH]]]]] )
Local $aFiles1 = _FileListToArrayRec($_sPath1, '*', $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_RELPATH)
If @error Then Return SetError(@error, 1) ; 9 - No files/folders found
Local $aFiles2 = _FileListToArrayRec($_sPath2, '*', $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_RELPATH)
If @error Then Return SetError(@error, 2)
; _ArraySort ( ByRef $aArray [, $iDescending = 0 [, $iStart = 0 [, $iEnd = 0 [, $iSubItem = 0 [, $iPivot = 0]]]]] )
_ArraySort($aFiles1, 0, 1) ; Muss für _ArrayBinarySearch! _ArraySearch geht auch ohne...
_ArraySort($aFiles2, 0, 1) ; Muss für _ArrayBinarySearch! _ArraySearch geht auch ohne...
;~ _ArrayDisplay($aFiles1, $_sPath1)
;~ _ArrayDisplay($aFiles2, $_sPath2)
; Spalten für FileTime (Last modified) und FileSize (Bytes) hinzufügen
_ArrayColInsert($aFiles1, 1) ; FileTime
_ArrayColInsert($aFiles1, 2) ; FileSize
_ArrayColInsert($aFiles2, 1)
_ArrayColInsert($aFiles2, 2)
For $i = 1 To $aFiles1[0][0] Step 1
$aFiles1[$i][1] = FileGetTime($_sPath1 & $sSlash1 & $aFiles1[$i][0], $FT_MODIFIED, $FT_STRING) ; YYYYMMDDHHMMSS
$aFiles1[$i][2] = FileGetSize($_sPath1 & $sSlash1 & $aFiles1[$i][0])
Next
For $i = 1 To $aFiles2[0][0] Step 1
$aFiles2[$i][1] = FileGetTime($_sPath2 & $sSlash2 & $aFiles2[$i][0], $FT_MODIFIED, $FT_STRING)
$aFiles2[$i][2] = FileGetSize($_sPath2 & $sSlash2 & $aFiles2[$i][0])
Next
;~ _ArrayDisplay($aFiles1, $_sPath1)
;~ _ArrayDisplay($aFiles2, $_sPath2)
;~ Exit
Local $aResult[0][7], $iIndex, $j = 1, $k = 1
While 1
If $j > $aFiles1[0][0] Then ExitLoop
; _ArraySearch ( Const ByRef $aArray, $vValue [, $iStart = 0 [, $iEnd = 0 [, $iCase = 0 [, $iCompare = 0 [, $iForward = 1 [, $iSubItem = -1 [, $bRow = False]]]]]]] )
;~ $iIndex = _ArraySearch($aFiles2, $aFiles1[$j][0], 1, 0, 0, 0, 1, 0)
; _ArrayBinarySearch ( Const ByRef $aArray, $vValue [, $iStart = 0 [, $iEnd = 0 [, $iColumn = 0]]] )
$iIndex = _ArrayBinarySearch($aFiles2, $aFiles1[$j][0], 1, 0, 0) ; _ArrayBinarySearch ist schneller als _ArraySearch - das Array muss aber sortiert sein!
; _FileListToArrayRec mit $FLTAR_SORT geht dafür nicht, deshalb das _ArraySort!
If $iIndex > -1 Then
If $aFiles2[$iIndex][1] = $aFiles1[$j][1] Then
_ArrayAdd($aResult, StringFormat('%s|%s|%s|==|%s|%s|%s', _
$_sPath1 & $sSlash1 & $aFiles1[$j][0], $aFiles1[$j][2], $aFiles1[$j][1], _
$aFiles2[$iIndex][1], $aFiles2[$iIndex][2], $_sPath2 & $sSlash2 & $aFiles2[$iIndex][0]))
ElseIf $aFiles2[$iIndex][1] > $aFiles1[$j][1] Then
_ArrayAdd($aResult, StringFormat('%s|%s|%s|<-|%s|%s|%s', _
$_sPath1 & $sSlash1 & $aFiles1[$j][0], $aFiles1[$j][2], $aFiles1[$j][1], _
$aFiles2[$iIndex][1], $aFiles2[$iIndex][2], $_sPath2 & $sSlash2 & $aFiles2[$iIndex][0]))
Else
_ArrayAdd($aResult, StringFormat('%s|%s|%s|->|%s|%s|%s', _
$_sPath1 & $sSlash1 & $aFiles1[$j][0], $aFiles1[$j][2], $aFiles1[$j][1], _
$aFiles2[$iIndex][1], $aFiles2[$iIndex][2], $_sPath2 & $sSlash2 & $aFiles2[$iIndex][0]))
EndIf
Else
_ArrayAdd($aResult, StringFormat('%s|%s|%s|->', _
$_sPath1 & $sSlash1 & $aFiles1[$j][0], $aFiles1[$j][2], $aFiles1[$j][1]))
EndIf
$j += 1
WEnd
While 1
If $k > $aFiles2[0][0] Then ExitLoop
$iIndex = _ArraySearch($aFiles1, $aFiles2[$k][0])
If $iIndex = -1 Then _ArrayAdd($aResult, StringFormat('|||<-|%s|%s|%s', _
$aFiles2[$k][1], $aFiles2[$k][2], $_sPath2 & $sSlash2 & $aFiles2[$k][0]))
$k += 1
WEnd
Return $aResult
EndFunc ;==>_CompareDirs
Alles anzeigen