Jump to content

File copy to only copy files that are new or changed


 Share

Recommended Posts

Thanks for the reply.

Got a quick question.

I have about 100 files ish. If I compared all the files then would this take quite a long time?.

I presume I would need to do something like "\*" and compare the local files with the files stored on the backup and if they are different then copy them.

Thought it was going to be easier than this but I guess I will just have to create some code to deal with this.

Thanks

Link to comment
Share on other sites

Hi Jon!

No, 100 files isn't very much,don't worry.

Just list the selected files to an array and check them in a "For"- loop.

That shouldN#t take too much time.

Best regards,

senthor

f.ex. (didn't check it:)

#include <file.au3>
#include <date.au3>
$aNormal = _FileListToArray("C:\My docs")
local $sText
For $iCount = 1 to $aNormal[0]
    If FileExists("C:\Backup\" & $aNormal[$iCount]) then 
        $aNormFile = FileGetTime("C:\My docs\" & $aNormal[$iCount])
        $aNormFile = $aNormFile[0] & "/" & $aNormFile[1] & "/" & $aNormFile[2] & " " & $aNormFile[3] & ":" &  $aNormFile[4] & ":" &  $aNormFile[5]
        $aBackFile = FileGetTime("C:\Backup\" & $aNormal[$iCount])
        $aBackFile = $aBackFile[0] & "/" & $aBackFile[1] & "/" & $aBackFile[2] & " " & $aBackFile[3] & ":" &  $aBackFile[4] & ":" &  $aBackFile[5]
        If _DateDiff("s", $aNormFile, $aBackFile) > 0 Then
            FileCopy("C:\My docs\" & $aNormal[$iCount], "C:\Backup\" & $aNormal[$iCount])
            $sText &= $aNormal[$iCount] & @crlf
        EndIf
    Else
        FileCopy("C:\My docs\" & $aNormal[$iCount], "C:\Backup\" & $aNormal[$iCount])
        $sText &= $aNormal[$iCount] & @crlf
    EndIf
Next
Msgbox(0,"Files copied:", $sText)
Edited by senthor
Link to comment
Share on other sites

Thanks for the reply.

Got a quick question.

I have about 100 files ish. If I compared all the files then would this take quite a long time?.

I presume I would need to do something like "\*" and compare the local files with the files stored on the backup and if they are different then copy them.

Thought it was going to be easier than this but I guess I will just have to create some code to deal with this.

Thanks

Sometimes the command line can do powerful things for you, like list all files in descending date/time order:
#include <Constants.au3>
#include <Array.au3>

$sExtCmd = @ComSpec & ' /c DIR "' & @DocumentsCommonDir & '" /A:-D /O:D /T:W'
$iPID = Run($sExtCmd, @DocumentsCommonDir, @SW_HIDE, $STDOUT_CHILD)
$sStdOut = ""
Do
    $sStdOut &= StdoutRead($iPID)
Until ProcessExists($iPID) = 0

$avStdOut = StringSplit($sStdOut, @CRLF, 1)
For $n = $avStdOut[0] To 1 Step -1
; Delete unwanted lines from array
    If (StringStripWS($avStdOut[$n], 8) = "") Or _
            (StringIsInt(StringLeft($avStdOut[$n], 2)) = 0) Or _
            (StringMid($avStdOut[$n], 3, 1) <> "/") Then _ArrayDelete($avStdOut, $n)
Next
$avStdOut[0] = UBound($avStdOut) - 1
_ArrayDisplay($avStdOut, "Files sorted by date/time");### Tidy Error -> for is never closed in your script.

You could get into the COM scripting interface to FileSystemObject and get quite geeky, but the basics still work fairly well.

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

#include <file.au3>
#include <date.au3>
$aNormal = _FileListTreeToArray("C:\My docs", 1, "-D")
local $sText
For $iCount = 1 to $aNormal[0]
    If FileExists("C:\Backup\" & $aNormal[$iCount]) then 
        $aNormFile = FileGetTime("C:\My docs\" & $aNormal[$iCount])
        $aNormFile = $aNormFile[0] & "/" & $aNormFile[1] & "/" & $aNormFile[2] & " " & $aNormFile[3] & ":" &  $aNormFile[4] & ":" &  $aNormFile[5]
        $aBackFile = FileGetTime("C:\Backup\" & $aNormal[$iCount])
        $aBackFile = $aBackFile[0] & "/" & $aBackFile[1] & "/" & $aBackFile[2] & " " & $aBackFile[3] & ":" &  $aBackFile[4] & ":" &  $aBackFile[5]
        If _DateDiff("s", $aNormFile, $aBackFile) > 0 Then
            FileCopy("C:\My docs\" & $aNormal[$iCount], "C:\Backup\" & $aNormal[$iCount], 9)
            $sText &= $aNormal[$iCount] & @crlf
        EndIf
    Else
        FileCopy("C:\My docs\" & $aNormal[$iCount], "C:\Backup\" & $aNormal[$iCount], 9)
        $sText &= $aNormal[$iCount] & @crlf
    EndIf
Next
Msgbox(0,"Files copied:", $sText)

; Name...........: _FileListTreeToArray
; Description ...: List all files from the wished directiry with all files from all subfolders to an array.
; Syntax.........: _FileListTreeToArray($sPath[, $fRelation = 1[, $sType = ""[,$sSort = "N"]]])
; Parameters ....: $sPath - Path to the directory that has to be listed
;                  $fRelation - Optional: Path return type, "0" = absolute (default), "1" = relative
;                  $sType - Optional: Search type, see helptopic "FileGetAttrib"; possible : "RASHD", with "-" before for negotation:
;                  |R - Readonly
;                  |A - Archive
;                  |S - System
;                  |H - Hidden
;                  |D - Directory
;                  $sSort - Optional: Sort results, see "cmd.exe /K dir /?" at subpoint "order", with "-" before for negotation: possibilities:
;                  |N - Name, alphabetically
;                  |S - Size, smaller files first
;                  |E - Extension, alphabetically
;                  |D - Date/Time, older files first
;                  |G - Directories first
; Return values .: Success - Array with $array[0] = Number of items, $array[n] = path of items
;                  Failure - Returns 0 and Sets @Error:
;                  |0 - No error.
;                  |1 - Invalid $sPath
;                  |2 - Invalid $fRelation
;                  |3 - Invalid $sType
;                  |4 - Invalid $sSort
;                  |5 - User32.dll failure
; Author ........: Jonas Neef
; Remarks .......: Caution: This function can take very long! Wildcards are supported.
; Related .......: FileGetAttrib, FileSetAttrib, _FileListToArray
; Link ..........;
; Example .......; Yes
Func _FileListTreeToArray($sPath, $fRelation = 0, $sType = "", $sSort = "N")
    local $aCheck, $vStdout, $sTemp, $sPlaceholder, $sTempSort, $vStdout, $sLine, $iCounter, $aReturn
    ; Check parameters, validate path
    $aCheck = StringLeft($sPath, 3)
    $aCheck = StringSplit($aCheck, ":" )
    If $aCheck[0] <> 2 and StringLeft($sPath, 1) <> "\" then $sPath = @WorkingDir & "\" & $sPath
    If $aCheck[0] <> 2 and StringLeft($sPath, 1) = "\" then $sPath = @WorkingDir & $sPath
    If StringRight($sPath, 1) = "\" then $sPath = StringTrimRight($sPath, 1)
    If Not FileExists($sPath) then Return Seterror(1, 0, 0)
    if $fRelation > 1 OR $fRelation < 0 then return Seterror(2, 0, 0)
    $sTempSort = StringReplace($sSort, "-", "")
    If StringLen($sTempSort) <> 1 or _
        $sTempSort <> "N" and _
        $sTempSort <> "S" and _
        $sTempSort <> "E" and _
        $sTempSort <> "D" and _
        $sTempSort <> "G" and _
        $sTempSort <> "" then _
        return Seterror(3, 0, 0)
    If Stringreplace( _
        Stringreplace( _
        Stringreplace( _
        Stringreplace( _
        Stringreplace( _
        Stringreplace($sType, "-", "") _
        , "H", "") _
        , "S", ""), _
        "A", ""), _
        "R", ""), _
        "D", "") <> "" then _
        return Seterror(4,0,0)
    ; Start CMD to load the tree
    If $sType = "" Then
        $vStdout = Run(@comspec & ' /C cd ..\..\..\..\.. & dir "' & $sPath & '" /A /B /O:' & $sSort & ' /S', @workingdir, @SW_HIDE, 6)
    Else
        $vStdout = Run(@comspec & ' /C cd ..\..\..\..\.. & dir "' & $sPath & '" /A:' & $sType & ' /B /O:' & $sSort & ' /S', @workingdir, @SW_HIDE, 6)
    EndIF
    ; Get data via Stdout
    While 1
        $sLine = StdoutRead($vStdout)
        If @error Then ExitLoop
        If $sLine <> "" then $sTemp &= $sLine
    Wend
    ; Create Placeholder for hole string
    For $iCounter = 0 To StringLen($sTemp)
        $sPlaceholder &= "  "
    Next
    ; Convert string from extended Ascii to Ansi
    $sTemp = DllCall("user32.dll", "long", "OemToChar", "str", $sTemp, "str", $sPlaceholder)
    $sPlaceholder = ""
    If Not Isarray($sTemp) or $sTemp[0] < 1 then return Seterror(5,0,0)
    $sTemp = $sTemp[2]
    ; Format finally
    $sTemp = StringReplace($sTemp, @crlf, @lf)
    $sTemp = StringReplace($sTemp, @cr, @lf)
    If StringRight($sTemp, 1) = @lf then $sTemp = StringTrimRight($sTemp, 1)
    If StringLeft($sTemp, 1) = @lf then $sTemp = StringTrimLeft($sTemp, 1)
    If Not StringInStr($sTemp, @lf) then
        If $sTemp = "" then
            local $aReturn[1] = [0]
        Else
            local $aReturn[2] = [1, $sTemp]
        EndIf
    Else
        local $aReturn = StringSplit($sTemp, @lf)
    EndIF
    if not isarray($aReturn) then
        Return Seterror(5,0,0)
    EndIF
    ; If relative path is chosen edit the paths
    If $fRelation = 1 Then
        For $iCounter = 1 To $aReturn[0] Step 1
            $aReturn[$iCounter] = StringReplace($aReturn[$iCounter], $sPath & "\", "")
        Next
    EndIf
    ; Return array
    return Seterror(0,0,$aReturn)
EndFunc   ;==>_FileReadTreeInArray

Edited by senthor
Link to comment
Share on other sites

Thanks.

I'm a bit confused what the code is checking though :-)

Cheers, Jon

It just gets a list of the files in an array in Date/Time order so it will be easy to find the ones you want. I was just pointing out that simple DOS command line stuff like DIR can help with this kind of thing. It's surprisingly fast too. Open a command line and do "DIR /?" to see what the switched did.

To use that for what you originally asked, you would have to define "new" better. I assumed "newer than a certain number of days", or something like that. If all you meant was "Archive bit set", then there are other things that might be even easier.

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Hi,

I have used Robocopy before but for my situation I cannot use this.

Hopefully I can put together some simple code that will just overwrite modified files and copy new files. My biggest problem is that I want to keep the following function in place:

_FileCopy ($working_location, $backup_location & @computername)

Func _FileCopy($fromFile,$tofile)
    Local $FOF_RESPOND_YES = 16
    Local $FOF_SIMPLEPROGRESS = 256
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($tofile).CopyHere($fromFile,$FOF_RESPOND_YES)
EndFunc

Thanks

Edited by jbennett
Link to comment
Share on other sites

I can't. This code is part of a larger program that I've written.

At the moment i've got it to overwrite the data each time it runs the backup.

Just looking at ways of cutting down the amount of time it takes after the first backup.

cheers

p.s. thanks for the link to synctoy though, i've never heard of it before and I work as an IT Administrator so it could be quite useful in the future :-)

Edited by jbennett
Link to comment
Share on other sites

XCOPY is very quick and versatile for this sort of thing.

; Copy new and changed files including sub directories to Backup location
RunWait(@ComSpec & " /c " & "xcopy " & '"C:\Applications\AutoIt Scripts" "H:\Backup\Applications\AutoIt Scripts" /D /E /C /R /H /I /K /Y')

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Link to comment
Share on other sites

That's a good idea :-)

RunWait(@ComSpec & " /c " & "xcopy " & '"C:\Applications\AutoIt Scripts" "H:\Backup\Applications\AutoIt Scripts" /D /E /C /R /H /I /K /Y')

How would I modify this so that I can use the data in my .ini file instead. Struggling to get it right.

I want to add 3 bits of information to this.

$working_location

$backup_location & @computername

Thanks

Edited by jbennett
Link to comment
Share on other sites

  • 5 months later...

Hi,

When I run xcopy with runwait() its output doesn't appear. When I added the option that causes handles to be inherited (not documented in the RunWait page) it would then show xcopy output when I ran the script from cmd prompt after compiling as a console program. However, when I redirected output with > or ran it from TextPad, my AutoIt script output appeared but the xcopy output did not. I think output from other commands, like dir, does appear. What's going on with xcopy?

Gary

Link to comment
Share on other sites

  • 1 year later...

After i tried xcopy in a script i only got 100 or so dos windows opened and then closed without copiing anything. Can somebody help me out?

Your best bet for help is to open a new topic and include your source code. It's hard to troubleshoot the issue based on the information you've given us.

-Mike

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...