Jump to content
Sign in to follow this  
cypher175

DirCopy & Auto Renaming If Source & Dest Files are Diff..?

Recommended Posts

cypher175

How would I go about coding a script to Mirror copy a Directory from one Drive to another Drive,

And if the Destination Folders or Files already exist with the same names as the Source Folders or Files then have it check and compare the Dest. Files against the Source Files with Either: "FileGetSize" & "FileGetTime" or "MD5" or "SHA1" -->Which ever one is the fastest if possible..??

And if any of the Source Files are Different from the Dest. Files then append (1) to the end of the already existing Destination file name Ex: FILE(1).TXT and if the FILE(1).TXT already exists then append (2) (3) (4) an So on Ect..

Then copy over the New Source File to the Dest. Dir.,

and if the Check-Compare Determines that the files are the same, then just have it skip that file and move on to the next file.. Ect..

So only the already existing destination files will get renamed with (1) (2) (3) (4) into their original file name, thus allowing to copy over the new source files with the conflicting same names..

Would this be possible to do with AutoIt at all..??

Share this post


Link to post
Share on other sites
rudi

[sync directories, special treatment for duplicate file names]

Would this be possible to do with AutoIt at all..??

Of course you can code that stuff using autoit. I personally prefer to use a mixture, Autoit and other tools together.

So I would use 3 steps:

1.) Robocopy source to a temp dir (free tool from Microsoft)

2.) temp dir to destination dir: I'd recommend to use Beyond Compare, to *MOVE* only files with unique file names (www.scootersoftware.com)

3.) Then write a Autoit Script to copy the remaining files in temp dir with unique file names to the destination dir.

But may I ask, what's your intention? Please describe your environment.

For most such sync tasks I either use "robocopy .... /mir" to *FORCE* the destination to be an *EXACT* mirror of the source. Or, if it's not in a LAN, but a WAN link, I use rsync (free unix tools, free Windows versions available in the web) with checksumming and delta copying the files (takes much less bandwidth).

Regards, Rudi.


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites
cypher175

thanks, but I would rather stick to only using AutoIt code instead to do this..

When using DirCopy and there is a error because there is a same name conflict with dest & source file how would I get that file name or path info extracted out to use in another "If" conditional statement..??

Or should i just gather all the source files into an array and set a variable that acquires each file name then checks if that file name already exists in the dest dir and if not then copies it over, but if it does exist- conflicts then set that dest file into a variale and then do a comparing of file size & timestamp and if they are diff then rename the dest so the source can be copied over..

I dunno maybe im going about this wrong..

what do you guys think would be the best way to do this using only autoit coding..??

I have Something like this so far..??

Sorry if doesn't make much, sense I just threw it together around 3:AM (really tired) so it probably doesn't really work as planned..

Could anyone help me out with this please..??

DirCopy("E:", "C:\E")
If @error = 0 Then
    MsgBox(0,"", @error)
    $SourceFilePath = "Source File Path"
    $SourceFileName = "Source File Name with Extension"
    $SourceFile = $SourceFilePath & $SourceFileName
    $DestFilePath = "Dest File Path"
    $DestFileName = "Dest File Name with Extension"
    $DestFile = $DestFilePath & $DestFileName
    $Num = 1 ; " Number That is Appended into Dest File Name "
    MsgBox(0,"", "Failed To Copy, Source File "& $SourceFile &" Because it Already Exists in the Destination Directory")
    If FileGetSize($SourceFile) <> FileGetSize($DestFile) then
        FileMove($DestFile, $DestFilePath & $SourceFileName &"("&$Num&")")
        If @error = 0 then
            EnvSet($Num, $Num + 1)
        FileMove($DestFile, $DestFilePath & $SourceFileName &"("&$Num&")")
        EndIf
        FileCopy($SourceFile, $DestFilePath & $SourceFileName)
    EndIf   
    EndIf

Share this post


Link to post
Share on other sites
cypher175

Im not sure if im coding this the right way but i want to compare the files in c:\e with those in E:\

How exactly would i do this so i can incorporate this feature into my previous post..??

#include <Array.au3>

#include <RecursiveFileSearch.au3>

$FileList-1=RecursiveFileSearch("E:\", ".", ".", 0, true, 0)

$FileList-2=RecursiveFileSearch("C:\E\", ".", ".", 0, true, 0)

_ArrayDisplay($FileList-1,"")

_ArrayDisplay($FileList-2,"")

For $i = 1 to $FileList[0]

If FileGetSize($FileList[$i]) <> FileGetSize($FileList2[$i]) then

???????

EndIf

Next

Share this post


Link to post
Share on other sites
martin

How would I go about coding a script to Mirror copy a Directory from one Drive to another Drive,

And if the Destination Folders or Files already exist with the same names as the Source Folders or Files then have it check and compare the Dest. Files against the Source Files with Either: "FileGetSize" & "FileGetTime" or "MD5" or "SHA1" -->Which ever one is the fastest if possible..??

And if any of the Source Files are Different from the Dest. Files then append (1) to the end of the already existing Destination file name Ex: FILE(1).TXT and if the FILE(1).TXT already exists then append (2) (3) (4) an So on Ect..

Then copy over the New Source File to the Dest. Dir.,

and if the Check-Compare Determines that the files are the same, then just have it skip that file and move on to the next file.. Ect..

So only the already existing destination files will get renamed with (1) (2) (3) (4) into their original file name, thus allowing to copy over the new source files with the conflicting same names..

Would this be possible to do with AutoIt at all..??

It is normally sufficient to say that if the file dates are the same and the file names are the same and the file sizes are the same then the files are the same. Your idea of having two arrays which you compare wouldn't work because the Nth item in one list might be the (N+6)th in the other. You need to go though each file with FileFindNextFile, see if it exists in the destination folder, compare the size and dates and rename or copy as needed.

It would be nice if you could use explorer and I tried playing with that, but it doesn't work if you have subfolders. If there are no subfolders you can use explorer to give a list of all duplicate names and work out how to rename them. In case it's any use I'll keep my test for a few days.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
Tlem

Try this :

#include <File.au3>
#include "FileListToArray3.au3"
; Get it here : http://www.autoitscript.com/forum/index.php?showtopic=49396

Dim $Src = ".\Dir1"
Dim $File = "*"
Dim $Dst = ".\Dir2"
Dim $szDrive, $szDir, $szFName, $szExt

; _FileListToArray3($sPath, $sFilter = "*", $iFlag = 0, $iRecurse = 0, $iBaseDir = 1, $sExclude = "", $i_Options = 1)
$aFiles = _FileListToArray3($Src, $File, 1, 1, 0, 0)

For $i = 1 To $aFiles[0]
    _PathSplit($aFiles[$i], $szDrive, $szDir, $szFName, $szExt)
    $SrcFile = $Src & "\" & $szDrive & $szDir & $szFName & $szExt
    $DstFile = $Dst & "\" & $szDir & $szFName & $szExt
    
    If FileExists($DstFile) Then
        $DstFile = _IfIdenticalIncrement($SrcFile, $DstFile)
        If $DstFile <> "" Then
            FileCopy($SrcFile, $DstFile, 8)
        EndIf
    Else
        FileCopy($SrcFile, $DstFile, 8)
    EndIf
Next

Func _IfIdenticalIncrement($vSrcFile, $vDstFile)
    Local $Count = 0
; Get the modified date of the source file.
    $ScrVer = FileGetTime($vSrcFile, 0, 1)
    
; To get all elemnt of the distination file (in plan to add incremental number).
    _PathSplit($vDstFile, $szDrive, $szDir, $szFName, $szExt)

; Loop to increment the name of the file.
    While FileExists($vDstFile)
        $Count += 1
        $vDstFile = $szDrive & $szDir & $szFName & "(" & $Count & ")" & $szExt
    WEnd
    
; If file(1), it assume that is the first copy.
    If $Count = 1 Then
        Return $vDstFile
; If file(x-1) is identical then assume the file is already duplicated.
    ElseIf $ScrVer = FileGetTime($szDrive & $szDir & $szFName & "(" & $Count - 1 & ")" & $szExt, 0, 1) Then
        Return ""
; Else assume it is a new version.
    Else
        Return $vDstFile
    EndIf
EndFunc  ;==>_IfIdenticalIncrement


Best Regards.Thierry

Share this post


Link to post
Share on other sites
cypher175

cool thanks that seems to help me out quite a bit..

there's just a few things that I need to tweak in it though..

Instead of comparing the the modified Dates I'd rather have it compare the File Sizes or MD5 or SHA1 Ect..

and instead of appending (#) to the newly copied over files, I'd rather have it append (#) to the preexisting Dest. files, then copy over the source files..

What all would I need to change in your code to do that..??

Thank you very much for helping me out..!!!

Edited by cypher175

Share this post


Link to post
Share on other sites
Tlem

I'd rather have it compare the File Sizes or MD5 or SHA1 Ect..

The size may not be a reference, because if you change only 1 byte the size will not be different.

Of course the comparison with MD5 can be interesting, but it will increase the time of the copy process.

Also if you want it, get MD5 or SHA module from this link http://www.autoitscript.com/forum/index.php?showtopic=21010

Update the example by the directive #AutoIt3Wrapper_Plugin_Funcs in place of #compiler_plugin_funcs.

In my code, in the function _IfIdenticalIncrement replace the two FileGetTime by the use of MD5 module and play. :mellow:

Be sure that files are not in use because MD5 will not work on these files.

instead of appending (#) to the newly copied over files, I'd rather have it append (#) to the preexisting Dest. files, then copy over the source files..

Sorry I don't understand this part. Explain like for a baby, English isn't my natural language and I have some trouble to understand all expression.

Detail operation like I do it in spoiler tag of this link : http://www.autoitscript.fr/forum/viewtopic...?f=6&t=1931

Edited by Tlem

Best Regards.Thierry

Share this post


Link to post
Share on other sites
cypher175

why wouldn't the comparing of 2 similar file sizes with FileGetSize() work..??

It says it Returns the size of a file in bytes..!!

So if 2 similar files had only a 1byte difference, FileGetSize() wouldn't be able to recognize that then. or what.??

Instead of appending (#) to the newly copied over files, I'd rather have it append (#) to the preexisting Dest. files, then copy over the source files..

Sorry I don't understand this part. Explain like for a baby, English isn't my natural language and I have some trouble to understand all expression

Well when I ran your code it compared the modified dates & times of both source files & preexisting Dest. files, then it inserted the incremental number (1) into the file names of the source files that got copied over to the Dest. Dir.

but the preexisting Dest. files were exactly the same as the source files, so nothing should have been copied over. but yet it did copy over all the source files into the Dest. Dir. and then inserted (1) into their file name. this is because the modified file dates that were compared were different so the file comparison falsely determined that the exact same files were 2 different files thus allowing the coping to take place..

What I want to do is Compare the 2 Similar Source & Preexisting Dest. Files by their File Sizes, then if the Source File is <> than the Preexisting Dest. File Size then have it Rename the Preexisting Dest. File by inserting (1) into its File Name, then have it Copy over the Source File.. If the 2 Similar Files have the exact same File Sizes then Both the source & Dest files are to be left alone..

So what do I change in your code to do this..??

Func _IfIdenticalIncrement($vSrcFile, $vDstFile)
    Local $Count = 0
; Get the modified date of the source file.
    $ScrVer = FileGetTime($vSrcFile, 0, 1)
    
; To get all elemnt of the distination file (in plan to add incremental number).
    _PathSplit($vDstFile, $szDrive, $szDir, $szFName, $szExt)

; Loop to increment the name of the file.
    While FileExists($vDstFile)
        $Count += 1
        $vDstFile = $szDrive & $szDir & $szFName & "(" & $Count & ")" & $szExt
    WEnd
    
; If file(1), it assume that is the first copy.
    If $Count = 1 Then
        Return $vDstFile
; If file(x-1) is identical then assume the file is already duplicated.
    ElseIf $ScrVer = FileGetTime($szDrive & $szDir & $szFName & "(" & $Count - 1 & ")" & $szExt, 0, 1) Then
        Return ""
; Else assume it is a new version.
    Else
        Return $vDstFile
    EndIf
EndFunc  ;==>_IfIdenticalIncrement

Share this post


Link to post
Share on other sites
Tlem

So if 2 similar files had only a 1byte difference, FileGetSize() wouldn't be able to recognize that then. or what.??

I'm suprised that you do not know that. :(

Try this :

Create one file named file1.txt with the char A inside and one file named file2.txt with the char Z inside.

Do this to see the size of the 2 files :

MsgBox(64, "Info", FileGetSize("file1.txt") & " = " & FileGetSize("file2.txt"))

So, what do you think of that ... Surprised. :)

For the second part of the problem, after reading a long time your response, I understand now what you wish.

But my method was correct, just not in the correct direction for you.

I recognize that it is more logical to make it as you wish it so I modified the code that is more simply now and I added another method of comparison by FC.exe DOS command.

The comparison of last modified date is correct, but now I added in more size comparison.

You can, like I explain in code added your own comparison methods and in more you can concatenate it. :mellow:

New code :

#include <File.au3>
#include "FileListToArray3.au3"
; Get it here : http://www.autoitscript.com/forum/index.php?showtopic=49396

Dim $Src = ".\Dir1"
Dim $File = "*"
Dim $Dst = ".\Dir2"
Dim $szDrive, $szDir, $szFName, $szExt

; _FileListToArray3($sPath, $sFilter = "*", $iFlag = 0, $iRecurse = 0, $iBaseDir = 1, $sExclude = "", $i_Options = 1)
$aFiles = _FileListToArray3($Src, $File, 1, 1, 0, 0)

For $i = 1 To $aFiles[0]
    _PathSplit($aFiles[$i], $szDrive, $szDir, $szFName, $szExt)
    $SrcFile = $Src & "\" & $szDrive & $szDir & $szFName & $szExt
    $DstFile = $Dst & "\" & $szDir & $szFName & $szExt
    

    If FileExists($DstFile) Then
        If _FilesCompare($SrcFile, $DstFile, 1) And not @error Then
            $RevisionFile = _GetIncrementName($SrcFile, $DstFile)
            FileMove($DstFile, $RevisionFile, 8)
            FileCopy($SrcFile, $DstFile, 8)
        Else
            MsgBox(16, "Error", "Error in function call. Check " & @CRLF & _
            "Source/Destination files and compare mode ...")
        EndIf
    Else
        FileCopy($SrcFile, $DstFile, 8)
    EndIf
Next

Func _GetIncrementName($vSrcFile, $vDstFile)
    Local $Count = 1
    
; To get all element of the distination file (in plan to add incremental number).
    _PathSplit($vDstFile, $szDrive, $szDir, $szFName, $szExt)
    
; 1st increment of file.
    $vDstFile = $szDrive & $szDir & $szFName & "(" & $Count & ")" & $szExt

; Loop to increment the name of the old destination file.
    While FileExists($szDrive & $szDir & $szFName & "(" & $Count & ")" & $szExt)
        $Count += 1
        $vDstFile = $szDrive & $szDir & $szFName & "(" & $Count & ")" & $szExt
    WEnd

    Return $vDstFile
EndFunc ;==>_IfIdenticalIncrement

; $fSrc is the source file.
; $fDst is the destination file.
; $Mode is the comparison mode :
;               0 = date and size comparison
;               1 = FC.exe comparison.
; You can add your own comparison méthode in this function.
Func _FilesCompare($fSrc, $fDst, $Mode)
    if Not FileExists($fSrc) or Not FileExists($fDst)  Then 
        SetError(1)
        Return 1
    EndIf
    
    If $Mode = 0 Then
        If (FileGetTime($fSrc, 0, 1) <> FileGetTime($fDst, 0, 1)) Or (FileGetSize($fSrc) <> FileGetSize($fDst)) Then
            Return 1
        Else
            Return 0
        EndIf
    ElseIf $Mode = 1 Then 
        Return RunWait(@ComSpec & ' /c ' & 'FC "' & $fSrc & '" "' & $fDst & '"', "", @SW_HIDE )
    Else
        SetError(2)
        Return 1
    EndIf   
endfunc

Best Regards.Thierry

Share this post


Link to post
Share on other sites
cypher175

thank you so much Tlem..

work pretty good..

If I wanted to use the MD5 feature in your code how would i do that..??

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.