Что нового

Поиск отличий 2х больших массивов на примере синхронизации папок

Naisho

Знающий
Сообщения
86
Репутация
12
AutoIt: 3.3.8.1
Версия: 1.0

Категория: Автоматизация, Вспомогательные функции, Данные, Файловая система

Описание:
Нашёл на официальном форуме идею, позволяющую очень быстро сравнивать большие массивы - на её основе, как пример, сделал програмку синхронизации 2х папок.
Может кому пригодится.

Код/Пример:
Код:
#include-once
#include <Math.au3>
;
;==============================================================================================
; синхронизируемая папка №1 : $rootFolder_1 --> "d:\aaa"
; синхронизируемая папка №2 : $rootFolder_2 --> "e:\bbb"
;$method = 0 обе папки
;$method = 1 скопировать в папку 1 отсутствующие в ней файлы
;$method = 2 скопировать в папку 2 отсутствующие в ней файлы
;
;==============================================================================================
Func SubFunction_SyncroniseFolders($rootFolder_1,$rootFolder_2,$method = 0)

	If Not FileExists($rootFolder_1) Then Return SetError (1)
	If Not FileExists($rootFolder_2) Then Return SetError (2)
	If StringRegExp($method,"[^012]",0) Then Return SetError (3)
	
	Local $fileList_1 = __FileList($rootFolder_1,'*',1)
	Local $fileList_2 = __FileList($rootFolder_2,'*',1)
	Local $rootFolder_1_Len = StringLen($rootFolder_1)
	Local $rootFolder_2_Len = StringLen($rootFolder_2)

	Global $diffFileList[_Max(UBound($fileList_1),UBound($fileList_2))]

	If $method = 0 Or $method = 1 Then
		$diffFileList[0] = 0
		__FileListDiff_1from2($fileList_1, $rootFolder_1_Len, $fileList_2, $rootFolder_2_Len)

		For $i = 1 To $diffFileList[0]
			FileCopy($diffFileList[$i],StringReplace($diffFileList[$i],$rootFolder_2,$rootFolder_1),8)
		Next
	EndIf

	If $method = 0 Or $method = 2 Then
		$diffFileList[0] = 0
		__FileListDiff_1from2($fileList_2, $rootFolder_2_Len, $fileList_1, $rootFolder_1_Len)

		For $i = 1 To $diffFileList[0]
			FileCopy($diffFileList[$i],StringReplace($diffFileList[$i],$rootFolder_1,$rootFolder_2),8)
		Next
	EndIf
EndFunc
;==============================================================================================
;
;==============================================================================================
Func __FileListDiff_1from2($fileList_1, $rootFolder_1_Len, $fileList_2, $rootFolder_2_Len)
	local $idx = 0
	For $i = 1 To $fileList_1[0]
		Assign('s' & StringToBinary(StringLower(StringTrimLeft($fileList_1[$i],$rootFolder_1_Len)),2),1,1)
	Next
	For $i = 1 To $fileList_2[0]
        If Not eval('s' & StringToBinary(StringLower(StringTrimLeft($fileList_2[$i],$rootFolder_2_Len)),2)) Then
			$idx += 1
			$diffFileList[$idx] = $fileList_2[$i]
        EndIf
	Next
	$diffFileList[0] = $idx
EndFunc
;==============================================================================================
;
;==============================================================================================
Func __FileList($sPath, $sFileMask, $iFlag = 0)
	Local $sOut, $aOut, $sRead, $hDir, $sAttrib, $aMasks
	Switch $iFlag
		Case 1
			$sAttrib = ' /A-D'
		Case 2
			$sAttrib = ' /AD'
		Case Else
			$sAttrib = ' /A'
	EndSwitch
	$sOut = StringToBinary('0' & @CRLF, 2)
	$aMasks = StringSplit($sFileMask, ';')
	For $i = 1 To $aMasks[0]
		$hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '" /S /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
		While ProcessExists($hDir)
			$sRead = StdoutRead($hDir, False, True)

			If @error Then
				ExitLoop
			EndIf
			If $sRead <> "" Then
				$sOut &= $sRead
			EndIf
		WEnd
	Next
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)

	If @error Then
		Return SetError(1)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc
;==============================================================================================

История версий:
первая и единственная версия

Источник: autoit-script.ru
Автор(ы): Отвёрочная сборка - Naisho :laugh:
 
Верх