Jump to content

Copying an entire directory structure without overwriting


Recommended Posts

I'm trying to copy an entire directory structure without overwriting, but dirCopy isn't working for me, and neither is fileCopy.

I've tried using wildcards to do this, but it isn't working. The help file states that this will work:

; Method to copy a folder (with its contents)
DirCreate("C:\new")
FileCopy("C:\old\*.*", "C:\new\")

However, it does not. Can anyone offer me some suggestions?

Thanks!

Edited by sharrakor
Link to comment
Share on other sites

Ok, I just realized it was because I was getting a return value of 0. How do I avoid this though? I want to backup something three subdirectories deep on my flashdrive, but since i create files on my desktop, they will need to be added to the ones already on the flash drive. This is 4 GB worth of stuff, so I don't want to have to rewrite it all everytime.

Link to comment
Share on other sites

Ok, I just realized it was because I was getting a return value of 0. How do I avoid this though? I want to backup something three subdirectories deep on my flashdrive, but since i create files on my desktop, they will need to be added to the ones already on the flash drive. This is 4 GB worth of stuff, so I don't want to have to rewrite it all everytime.

FileCopy will copy files, Not a folder structure. For that you need to use DirCopy() With DrCopy your paths CAN NOT contain trailing backslashes.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I tried DirCopy, and if by trailing backslashes you mean the correct syntax is: dirCopy("c:\testmusic","K:\Music Backup",0), then I've already tried that.

So since DirCopy isn't working, is there a next best way to do it? If you need I can provide more details.

EDIT: dirCopy works, but not with the option to avoid overwriting enabled. All I want is to not overwrite the FILES.

Edited by sharrakor
Link to comment
Share on other sites

I tried DirCopy, and if by trailing backslashes you mean the correct syntax is: dirCopy("c:\testmusic","K:\Music Backup",0), then I've already tried that.

So since DirCopy isn't working, is there a next best way to do it? If you need I can provide more details.

EDIT: dirCopy works, but not with the option to avoid overwriting enabled. All I want is to not overwrite the FILES.

It doesn't overwrite the source files. That flag is for overwriting the destination files if they already exist. It you have file_X.txt in both the source and destination folders and you update the copy in the source folder, DirCopy() will overwrite the file in the Destination folder if the flag is set. If you don't want that then you would have to write a quick function to determine if the destination file already exists, if it does then rename the file before copying it.

If this doesn't answer the question then give us some details to work with here.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I found a way to do exactly what I want by using _RunDOS and a recursive function. I'll post the full code when I'm done (in case anyone Googles the same question).

However, to complete it, I need to know: After doing _RunDOS, is there a way to pass in a character to the same DOS window? For example, if I do:

xcopy "K:" "C:\from k" /t

It will ask me if I want to overwrite, which I do not. Is there a way to pass an "n" to it?

Link to comment
Share on other sites

I found a way to do exactly what I want by using _RunDOS and a recursive function. I'll post the full code when I'm done (in case anyone Googles the same question).

However, to complete it, I need to know: After doing _RunDOS, is there a way to pass in a character to the same DOS window? For example, if I do:

xcopy "K:" "C:\from k" /t

It will ask me if I want to overwrite, which I do not. Is there a way to pass an "n" to it?

'n' meaning 'recursive' ?

Try '/E'.

Link to comment
Share on other sites

This do what you want . The only difference is to overwrite only files that the size or modified date are different.

$sSource = 'C:\Old'
$sTarget = 'C:\New'
If StringRight($sSource, 1) = '\' Then $sSource = StringTrimRight($sSource, 1)
If StringRight($sTarget, 1) = '\' Then $sTarget = StringTrimRight($sTarget, 1)

$aCopyList = _FileListToArrayEx($sSource, '*', 1)
If IsArray($aCopyList) Then
    For $x = 1 To $aCopyList[0]
        $sDest = $sTarget & StringReplace($aCopyList[$x], $sSource, '')
        $iSize = FileGetSize($aCopyList[$x]) - FileGetSize($sDest)
        If $iSize <> 0 Or FileGetTime($aCopyList[$x], 0, 1) <> FileGetTime($sDest, 0, 1) Then FileCopy($aCopyList[$x], $sDest, 9)
    Next
EndIf

Func _FileListToArrayEx($sPath, $sFilter = '*', $iFlag = 0, $iRecursive = 1, $iRunFirstTime = 1)
    Local $aFileList = '', $aFolderList = '', $Tmp = ''
    Local $aBadChar[6] = ['\', '/', ':', '>', '<', '|']
    
    If StringRight($sPath, 1) = '\' Then $sPath = StringTrimRight($sPath, 1)
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    For $iCC = 0 To UBound($aBadChar) - 1
        If StringInStr($sFilter, $aBadChar[$iCC]) Then Return SetError(2, 2, "")
    Next
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")

    $sFilter = StringReplace($sFilter, '\', '')
    $iFirstFile = FileFindFirstFile($sPath & '\' & $sFilter)
    If @error Then Return
    
    While 1     
        $iNextFile = FileFindNextFile($iFirstFile)
        If @error Then ExitLoop
        $sFullPath = $sPath & '\' & $iNextFile
        If StringInStr(FileGetAttrib($sFullPath), "D") Then
            If $iFlag <> 1 Then $aFileList &= $sFullPath & @CRLF
            If $iRecursive Then 
                $Tmp = _FileListToArrayEx($sFullPath, $sFilter, $iFlag, $iRecursive = 1, 0)
                If $Tmp <> Chr(38) And $Tmp <> ChrW(38) Then $aFileList &= $Tmp
            EndIf
        Else
            If $iFlag <> 2 Then $aFileList &= $sFullPath & @CRLF
        EndIf
    WEnd    
    FileClose($iFirstFile)

    If $iRunFirstTime Then      
        If $sFilter <> '*' And $sFilter <> '*.*' And $iRecursive Then
            $aFolderList = _FileListToArrayEx($sPath, '*.*', 2, 1, 0)
            $aFolderList = StringSplit(StringTrimRight($aFolderList, 2), @CRLF, 1)          
            For $x = 1 To $aFolderList[0]
                $Tmp = _FileListToArrayEx($aFolderList[$x], $sFilter, $iFlag, $iRecursive, 0)
                If $Tmp <> Chr(38) And $Tmp <> ChrW(38) Then $aFileList &= $Tmp
            Next        
        EndIf
        $aFileList = StringSplit(StringTrimRight($aFileList, 2), @CRLF, 1)
        If $aFileList[$aFileList[0]] = '' Then Return SetError(4, 4, "")
    EndIf
    Return SetError(0, 0, $aFileList)
EndFunc

AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line
Link to comment
Share on other sites

'n' meaning 'recursive' ?

Try '/E'.

No. I mean if it comes up with a question, such as: "Do you want to overwrite?" after I enter in my command, how do I prevent that from hanging my script if I'm running it in a hidden window (I want to give it a response)?

Also, thanks Danny, but I came up with this before I saw your post.

local $currentDir=$userMusicPath;place to copy files from, no trailing backslash
local $dirToCopyTo=$driveLetter;place to copy files to, drive path of flash drive with the correct name as dertermined earlier. no trailing backslash
local $sourceTest=fileGetTime($currentDir,1,1)
if ($sourceTest<>"") then
    _RunDOS("xcopy """&$currentDir&""" """&$dirToCopyTo&""" /t /e /y")
    copyFiles($currentDir,$dirToCopyTo,$currentDir)
else
    msgbox(0,"Error","The source folder doesn't exist.")
endif

;the func itself

func copyFiles($currentDir,$dirToCopyTo,$currentDirOrig);recursive
    fileChangeDir($currentDir)
    local $searchThis=fileFindFirstFile("*.")
    local $newFolderName=fileFindNextFile($searchThis)
    while $newFolderName<>""
        copyFiles(($currentDir&"\"&$newFolderName),$dirToCopyTo,$currentDirOrig)
        $newFolderName=fileFindNextFile($searchThis)
    wend
    local $temp=stringreplace($currentDir,$currentDirOrig,$dirToCopyTo)
    filecopy($currentDir&"\*.*",$temp&"\",0)
endfunc
Edited by sharrakor
Link to comment
Share on other sites

Take a look at that link, you can add a parameter to your line in DOS to leave out the overwrite prompt.

http://www.ss64.com/nt/xcopy.html

Yes, thats what I did, but I believe it leaves it out by overwriting it anyway, which I don't want to do. I used /y.

A better question would be, if I use _RunDOS to run something in a hidden DOS window, and it needs a confirmation or input of some sort after I enter the command ("Are you sure?" ect), what do I do? How can I give it the input it needs?

Edited by sharrakor
Link to comment
Share on other sites

So you want it to automatically NOT overwrite the files? Let me look into that for a sec ; )

so far this is what I've came up with, creating a .bat file to help you out with this.

for /f %%a in ('xcopy "D:\test\*.*" "D:\test2" /L /Y') do (
    if not exist "D:\test2\%%~nxa" xcopy "%%a" "D:\test2" /Y
)
pause

for some reason it's taking space characters as the end of a filename but idk how to solve that, I'm not that good at batch scripting.

Edited by toonboon

[right]~What can I say, I'm a Simplistic person[/right]

Link to comment
Share on other sites

I'm trying to copy an entire directory structure without overwriting, but dirCopy isn't working for me, and neither is fileCopy.

I've tried using wildcards to do this, but it isn't working. The help file states that this will work:

; Method to copy a folder (with its contents)
DirCreate("C:\new")
FileCopy("C:\old\*.*", "C:\new\")

However, it does not. Can anyone offer me some suggestions?

Thanks!

Hi,

you could use _FileChangeRecursive() http://www.autoitscript.com/forum/index.ph...c=40542&hl=

with these worker functions (with/without overwrite). NOT TESTED, but should work!

#include "_FileChangeRecursive.au3"

$retval = _FileChangeRecursive("C:\temp","*.au3",-1,"_BackupFile_Overwrite","C:\temp","c:\backup")
$retval = _FileChangeRecursive("C:\temp","*.au3",-1,"_BackupFile_NO_Overwrite","C:\temp","c:\backup_no_overwrite")


func _BackupFile_Overwrite($filepath,$basepath,$backupfolder)
    Local $relpath = StringReplace($filepath,$basepath,"")
        FileCopy($filepath,$backupfolder & $relpath,8)
endfunc

func _BackupFile_NO_Overwrite($filepath,$basepath,$backupfolder)
    Local $relpath = StringReplace($filepath,$basepath,"")
        FileCopy($filepath,$backupfolder & $relpath,8+1)
endfunc

Kurt

__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Link to comment
Share on other sites

Hi,

you could use _FileChangeRecursive() http://www.autoitscript.com/forum/index.ph...c=40542&hl=

with these worker functions (with/without overwrite). NOT TESTED, but should work!

#include "_FileChangeRecursive.au3"

$retval = _FileChangeRecursive("C:\temp","*.au3",-1,"_BackupFile_Overwrite","C:\temp","c:\backup")
$retval = _FileChangeRecursive("C:\temp","*.au3",-1,"_BackupFile_NO_Overwrite","C:\temp","c:\backup_no_overwrite")


func _BackupFile_Overwrite($filepath,$basepath,$backupfolder)
    Local $relpath = StringReplace($filepath,$basepath,"")
        FileCopy($filepath,$backupfolder & $relpath,8)
endfunc

func _BackupFile_NO_Overwrite($filepath,$basepath,$backupfolder)
    Local $relpath = StringReplace($filepath,$basepath,"")
        FileCopy($filepath,$backupfolder & $relpath,8+1)
endfunc

Kurt

True. Mine works at this point for the current situation, but thanks for the tip. Could come in handy.
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...