Sign in to follow this  
Followers 0
AlchemistZim

dircopy with sub directories no overwrite

9 posts in this topic

#1 ·  Posted (edited)

i'm trying to copy a directory with sub folders, and not overwrite existing files.

in testing i have 2 directories (1,2).

directory-1 has 3 txt files (a,b,c), and a sub folder (z), with 3 txt files (1,2,3)

directory-2 has 3 txt files (a,b,c), that are different than the files in directory-1

i want to copy the files from directory-1 to directory-2, and not overwrite the existing files

DirCopy (@DesktopDir & "\test\dumb", @DesktopDir & "\test\stupid", 0) = no files copied

DirCopy (@DesktopDir & "\test\dumb", @DesktopDir & "\test\stupid", 1) = files copied, and overwritten, with sub directory & files

FileCopy (@DesktopDir & "\test\dumb\*.*", @DesktopDir & "\test\stupid\", 0) = files copied, not overwritten, no sub directory

FileCopy (@DesktopDir & "\test\dumb\*.*", @DesktopDir & "\test\stupid\", 1) = files copied, and overwritten, no sub directory

FileCopy (@DesktopDir & "\test\dumb\*.*", @DesktopDir & "\test\stupid\", 8) = files copied, not overwritten, no sub directory

FileCopy (@DesktopDir & "\test\dumb\*.*", @DesktopDir & "\test\stupid\", 9) = files copied, and overwritten, no sub directory

what i want is "files copied, not overwritten, with sub directory & files"...does anyone know of a way to get this result???

Edited by AlchemistZim

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

one way

#include <Array.au3>
Local $SourceFolder = @DesktopDir & "\test\dumb"
Local $DestinationFolder = @DesktopDir & "\test\stupid"

Local $Array = _FileListToArrayRecursive($SourceFolder, "*", 1, 1)
If Not IsArray($Array) Or Not $Array[1] Then Exit Msgbox(4096, 'No Files Found', 'Cannot Find any Files in ' & $SourceFolder)

Local $CopyArray[$Array[0] + 1][2]
$CopyArray[0][0] = $Array[0]

For $i = 1 to $Array[0]
    $CopyArray[$i][0] = $Array[$i]
    $CopyArray[$i][1] =  StringRegExpReplace($Array[$i], StringReplace($SourceFolder, "\", "\\"), StringReplace($DestinationFolder, "\", "\\"))
Next

_ArrayDisplay($CopyArray) ; 2 Dimensional Array with Source File Path and Destination File Path

For $i = 1 to $CopyArray[0][0]
    FileCopy($CopyArray[$i][0], $CopyArray[$i][1], 8)
Next

Func _FileListToArray_Recursive($sPath, $sFilter = "*", $iRetItemType = 0, $iRetPathType = 0, $bRecursive = False)
    Local $sRet = "", $sRetPath = ""
    $sPath = StringRegExpReplace($sPath, "[\\/]+\z", "")
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If StringRegExp($sFilter, "[\\/ :> <\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
    $sPath &= "\|"
    $sOrigPathLen = StringLen($sPath) - 1
    While $sPath
        $sCurrPathLen = StringInStr($sPath, "|") - 1
        $sCurrPath = StringLeft($sPath, $sCurrPathLen)
        $Search = FileFindFirstFile($sCurrPath & $sFilter)
        If @error Then
            $sPath = StringTrimLeft($sPath, $sCurrPathLen + 1)
            ContinueLoop
        EndIf
        Switch $iRetPathType
            Case 1 ; relative path
                $sRetPath = StringTrimLeft($sCurrPath, $sOrigPathLen)
            Case 2 ; full path
                $sRetPath = $sCurrPath
        EndSwitch
        While 1
            $File = FileFindNextFile($Search)
            If @error Then ExitLoop
            If ($iRetItemType + @extended = 2) Then ContinueLoop
            $sRet &= $sRetPath & $File & "|"
        WEnd
        FileClose($Search)
        If $bRecursive Then
            $hSearch = FileFindFirstFile($sCurrPath & "*")
            While 1
                $File = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If @extended Then $sPath &= $sCurrPath & $File & "\|"
            WEnd
            FileClose($hSearch)
        EndIf
        $sPath = StringTrimLeft($sPath, $sCurrPathLen + 1)
    WEnd
    If Not $sRet Then Return SetError(4, 4, "")
    Return StringSplit(StringTrimRight($sRet, 1), "|")
EndFunc   ;==>_FileListToArray_Recursive

Edited by Varian

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

one way

i need to do this twice. so i would past the code twice in my script, and just replace the source and destination with where it actually needs to be? Edited by AlchemistZim

Share this post


Link to post
Share on other sites

Made this into a function

#include <Array.au3>

_CopyFolderNoOverwrite(@DesktopDir & "\test\dumb", @DesktopDir & "\test\stupid")    ;First Run
_CopyFolderNoOverwrite(@DesktopDir & "\test\dumb2", @DesktopDir & "\test\stupid2")  ;2nd Run

Func _CopyFolderNoOverwrite($SourceFolder, $DestinationFolder)
    Local $Array = _FileListToArray_Recursive($SourceFolder, "*", 1, 2, 1)
    If Not IsArray($Array) Or Not $Array[1] Then Return MsgBox(4096, 'No Files Found', 'Cannot Find any Files in ' & $SourceFolder)
    Local $CopyArray[$Array[0] + 1][2]
    $CopyArray[0][0] = $Array[0]
    For $i = 1 To $Array[0]
        $CopyArray[$i][0] = $Array[$i]
        $CopyArray[$i][1] = StringRegExpReplace($Array[$i], StringReplace($SourceFolder, "\", "\\"), StringReplace($DestinationFolder, "\", "\\"))
    Next
    _ArrayDisplay($CopyArray); 2 Dimensional Array with Source File Path and Destination File Path
    For $i = 1 To $CopyArray[0][0]
        FileCopy($CopyArray[$i][0], $CopyArray[$i][1], 8)
    Next
EndFunc   ;==>_CopyFolderNoOverwrite

;===============================================================================
; $iRetItemType: 0 = Files and folders, 1 = Files only, 2 = Folders only
; $iRetPathType: 0 = Filename only, 1 = Path relative to $sPath, 2 = Full path/filename
Func _FileListToArray_Recursive($sPath, $sFilter = "*", $iRetItemType = 0, $iRetPathType = 0, $bRecursive = False)
    Local $sRet = "", $sRetPath = ""
    $sPath = StringRegExpReplace($sPath, "[\\/]+\z", "")
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If StringRegExp($sFilter, "[\\/ :> <\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
    $sPath &= "\|"
    $sOrigPathLen = StringLen($sPath) - 1
    While $sPath
        $sCurrPathLen = StringInStr($sPath, "|") - 1
        $sCurrPath = StringLeft($sPath, $sCurrPathLen)
        $Search = FileFindFirstFile($sCurrPath & $sFilter)
        If @error Then
            $sPath = StringTrimLeft($sPath, $sCurrPathLen + 1)
            ContinueLoop
        EndIf
        Switch $iRetPathType
            Case 1 ; relative path
                $sRetPath = StringTrimLeft($sCurrPath, $sOrigPathLen)
            Case 2 ; full path
                $sRetPath = $sCurrPath
        EndSwitch
        While 1
            $File = FileFindNextFile($Search)
            If @error Then ExitLoop
            If ($iRetItemType + @extended = 2) Then ContinueLoop
            $sRet &= $sRetPath & $File & "|"
        WEnd
        FileClose($Search)
        If $bRecursive Then
            $hSearch = FileFindFirstFile($sCurrPath & "*")
            While 1
                $File = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If @extended Then $sPath &= $sCurrPath & $File & "\|"
            WEnd
            FileClose($hSearch)
        EndIf
        $sPath = StringTrimLeft($sPath, $sCurrPathLen + 1)
    WEnd
    If Not $sRet Then Return SetError(4, 4, "")
    Return StringSplit(StringTrimRight($sRet, 1), "|")
EndFunc   ;==>_FileListToArray_Recursive

Share this post


Link to post
Share on other sites

Made this into a function

ok so just past the functions at the end of my script, and use the commands correct???

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Yes...the functions (can) go at the end and the command is:

_CopyFolderNoOverwrite("YourSourceFolder", "YourDestinationFolder")
Make sure you specify Full paths with Drive Letter

Edited by Varian

Share this post


Link to post
Share on other sites

Yes...the functions (can) go at the end and the command is:

_CopyFolderNoOverwrite("YourSourceFolder", "YourDestinationFolder")

sweet...thanks

Share this post


Link to post
Share on other sites

sweet...thanks

1 problem... it comes up with an array window where u have to select what files to copy...

what about this

DirCopy (@DesktopDir & "\test\stupid", @DesktopDir & "\test\stupid.org", 1)
DirCopy (@DesktopDir & "\test\dumb", @DesktopDir & "\test\stupid", 1)
DirCopy (@DesktopDir & "\test\stupid.org", @DesktopDir & "\test\stupid", 1)
DirRemove (@DesktopDir & "\test\stupid.org", 1)

all i did was (1)copy the destination to a temp folder, (2)copy the source to the destination letting it overwrite all the files, and (3) then copy the temp folder back to the destination, (4) and delete the temp directory...do you think that would work???

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

You would still have 2 problems.

You would not copy Sub Directories with the FileCopy and 1 Flag..it would have to be 1 + 8 or 9

You would overwrite the files when you use the 1 flag to copy back to your destination (and not copy sub directories again)

Just comment out any lines that you don't need by preceeding it with ";"...specifically change this line to

;_ArrayDisplay($CopyArray); 2 Dimensional Array with Source File Path and Destination File Path
Now the Array won't display..incidentally, when the Array displays it is not asking you to select the files to copy..it just shows you what the files in column 1 will be copied to in column 2

EDIT..You could accomplish the same thing with xcopy, but it is good to learn your AutoIT for future reference

Edited by Varian

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  
Followers 0