Problem mit DirCopy

  • Hallo, ich versuche hiermit "DirCopy("G:\daten\*.*", "U:\daten")" den Inhalt von "G:\daten" mit allen Unterverzeichnissen nach" u:\Daten" zu kopieren. Falls auf "u:\daten" schon Dateien existieren, sollen diese ausgelassen werden. Leider wird aber garnichts kopiert. Das Skript beendet sich ohne Fehlermeldung. Woran liegts? Ach ja, U. ist ein Netzlaufwerk.

    Gibt es vielleicht auch schon eine Funktion zum sychronisieren von Verzeichnissen?

    Danke

    igillan

    Einmal editiert, zuletzt von igillan (22. August 2009 um 13:18)

  • DirCopy("G:\daten\", "U:\daten\")

    versuch es mal so ;)


    Hab ich auch schon probiert. Vielleicht liegts an der Größe. Beide Verz. sind ca. 350 GB groß, mit sehr vielen Verzeichnissen und Dateien. Auf U: fehlen immer ein paar Dateien , da es auf G: immer mehr werden, und mit dem Befehl "DirCopy("G:\daten\", "U:\daten\") "sollte u: aktuell gehalten werden.

    P.S.

    "FileCopy("G:\daten\*.*", "U:\daten\",0)"

    habe ich auch schon erfolglos probiert.

    igillan

  • Das ist sehr komisch haste mal mit xcopy versucht ? ( RunDos )

    Dircopy funktioniert eiegntlich genauso
    bei der größe kann ich es dir nciht sagen ...
    Ich habe aber hier im Forum schonmla die möglickeit gesehen gehabt windows zum kopieren zu bewegen
    üder DLLCALL
    musste mal die sufu nutzen

  • Hi,
    vielleicht so:

    [autoit]


    DirCopy("G:\daten", "U:\daten")

    [/autoit]


    und schau mal in die Hilfe:

    Spoiler anzeigen


    DirCopy
    --------------------------------------------------------------------------------

    Kopiert einen Ordner samt Unterordner und Dateien (funktioniert wie xcopy)

    DirCopy ( "source dir", "dest dir" [, flag] )

    Parameter:
    source dir Pfad zum Quellordner ohne abschließenden Backslash (z.B. "C:\Path1")
    dest dir Pfad zum Zielordner ohne abschließenden Backslash (z.B. "C:\Path_Copy")
    flag [optional] dieser Parameter gibt an, ob eventuell schon existierende Dateien überschrieben werden sollen oder nicht.
    0 = (Standard) kein Überschreiben von existierenden Dateien
    1 = Überschreiben existierender Dateien

    Rückgabewert:
    Erfolg: Gibt 1 zurück.
    Fehler: Gibt 0 zurück wenn das Kopieren des Ordners fehlschlug.

    Bemerkungen:
    Wenn die Ordnerstruktur des Zielordners nicht besteht, wird sie nach Möglichkeit erstellt.

    Verwandte Funktionen
    DirRemove, FileCopy

    Beispiel:
    DirCopy(@MyDocumentsDir, "C:\Sicherungen\Eigene Dateien", 1)


    Viel Erfolg ! :thumbup:

  • Hi,
    und schau mal in die Hilfe:


    ...hab ich natürlich gemacht! An der Verzeichnisgröße liegt es auch nicht. Habe eben auf G: und U: ein Verzeichnis "test" angelegt . Dann ein weiteres Verz. mit ein paar Dateien nach G:\test kopiert.

    Dann das hier "DirCopy("G:\test", "U:\test")" und nichts passiert. Versteh ich nicht. ?(


    Zitat

    Das ist sehr komisch haste mal mit xcopy versucht ? ( RunDos )

    Bei xcopy finde ich keinen Parameter, wo im Ziel vorhandene Dateien ausgeklammert werden. Sie werden immer überschrieben. Da läuft das Skript bei 350GB ja immer ewig...

    igillan

    Einmal editiert, zuletzt von igillan (22. August 2009 um 14:06)

  • Du willst nur neuere dateinen kopieren ..
    hmm
    Wie wäre es mit einem rekursiven suche wo du sonst die datein selber überprüfst und die einzellnen dateinen ersetzen lässt die neuer sind

  • Ja, habe ich so "Msgbox(0,"","Fehler: " & @error)" abgefragt. Es wird "0" ausgegeben, aber nichts kopiert.

    "DirCopy("G:\test", "U:\test")" nichts passiert, Ordner u:\test bleibt leer. g:\test hat noch ein Unterverz. mit 10 Dateien. ?(

    bruce

    Einmal editiert, zuletzt von igillan (22. August 2009 um 17:34)

  • Mit Parameter werden alle überschrieben das ist sein Problem
    er will nur dateien ersetzen lassen die neuer sind da es ihm sonst zu lange dauert

    Daher muss er nach den Dateine rekusirv suchen und dann datei nach größe und veränderung prüfen und gegebenfalls ersetzen


    Bei mir funktioniert das auch wunderbar... mit allen überschreiben er kopiert bei mir auch die dateien so problemlos

    Nur was er genau machen will (Dateien nur abgleichen [Spiegeln] + nur neue bzw geänderte datein wirklich kopieren), da muss noch wenig mehr getan werden :)

    Daher empfehle ich ja die sufu zu nutzen rekursive dateisuche ( damit unterordner mit durchsucht werden )
    und anhand der file daten handeln ..


    _RecursiveFileListToArray.au3 <-- von Oscar
    + for schleife + FileGetTime + FileCopy
    Sollte das gewünschte ergebniss bringen ;)

  • Hi,
    ohne weiteren Code habe ich die folgende Zeile erfolgreich getestet.

    [autoit]


    DirCopy("C:\Tools", "D:\Tools2", 1)

    [/autoit]


    Alle Ordner und Unterverzeichnisse wurden übertragen ! :thumbup:


    so gehts bei mir auch. Aber durch flag1 werden ja existierende Dateien überschrieben,und nochmal kopiert. Das wollte ich eben durch Flag 0 oder gar keins umgehen, da die Verz. ca. 350 GB groß sind.

    Zitat

    RecursiveFileListToArray.au3 <-- von Oscar
    + for schleife + FileGetTime + FileCopy
    Sollte das gewünschte ergebniss bringen ;)

    ... ich glaub, da muß ich passen...

    igillan

    Einmal editiert, zuletzt von igillan (22. August 2009 um 19:14)

  • ganz einfach,
    in der Funktion "DirCopy" ist eine Prüfung der Zeitstempel der Dateien die kopiert werden sollen nicht implementiert.
    PS: ich empfehle: FastCopy
    Ist zwar nicht so umfangreich in den Einstellmöglichkeiten wie RoboCop aber mit das Schnellste was es gibt ;)

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

  • Habe mal eine UDF im Forum gefunden:

    Spoiler anzeigen
    [autoit]

    ;===============================================================================
    ; Function Name: _MultiFileCopy
    ; Description:: Kopiert mehrere Dateien mit Progressbar
    ; Parameter(s): Array mit Dateien zum kopieren oder Quellpfad,
    ; Zielpfad,
    ; überschreiben? [True/False],
    ; Wenn überschreiben = True, dann PreFix zum überschreiben
    ; Return Value(s): Array mit den kopierten Dateien
    ; Requirement(s): Global $strFiles = '', $strSize = 0
    ; #include<String.au3>
    ; #include<Misc.au3>
    ; Author(s): Tom99, progandy, eukalyptus and Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _MultiFileCopy($aSource, $sDestPath = '', $bOverWrite = True, $sPreFix = '!Copy')
    Local $oldGUICloseOnESC = Opt('GUICloseOnESC', 0)
    Local $ret, $sShowSource, $sShowDest, $sSourcePath = '', $sNewFolder = '', $k
    Local $aMFC[12] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, False, DllOpen('user32.dll')]
    If IsArray($aSource) Then
    If Not IsNumber($aSource[0]) Then Return SetError(1, 0, 0)
    For $i = 1 To $aSource[0]
    $aMFC[7] += FileGetSize($aSource[$i])
    Next
    Else
    $sSourcePath = $aSource
    If StringRight($sSourcePath, 1) <> '\' Then $sSourcePath &= '\'
    $strSize = 0
    ToolTip('Bitte warten! Verzeichnis wird eingelesen!', @DesktopWidth / 2 - 100, 10)
    If FileExists($sSourcePath & '!copydata.mfc') And $sDestPath <> '' Then
    Local $sFile = StringTrimRight(FileRead($sSourcePath & '!copydata.mfc'), 2)
    $strSize = StringLeft($sFile, StringInStr($sFile, @CRLF) - 1)
    $aSource = StringSplit(StringTrimLeft($sFile, StringInStr($sFile, @CRLF) + 1), @CRLF, 1)
    Else
    If FileExists($sSourcePath & '!copydata.mfc') Then FileDelete($sSourcePath & '!copydata.mfc')
    $aSource = _GetFilesFolder_Rekursiv($sSourcePath)
    Local $hFile = FileOpen($sSourcePath & '!copydata.mfc', 2)
    If $hFile <> -1 Then
    FileWriteLine($hFile, $strSize)
    For $i = 1 To $aSource[0]
    FileWriteLine($hFile, $aSource[$i])
    Next
    FileClose($hFile)
    EndIf
    EndIf
    $aMFC[7] = $strSize
    ToolTip('')
    If $sDestPath = '' Then Return SetError(0, 0, 1)
    EndIf
    If StringRight($sDestPath, 1) <> '\' Then $sDestPath &= '\'
    If Not FileExists($sDestPath) Then
    If Not DirCreate($sDestPath) Then Return SetError(2, 0, 0)
    EndIf
    $sShowDest = StringRegExpReplace($sDestPath, '(.{15})(.*)(.{35})', '$1' & '[...]' & '$3')
    Local $aReturn = $aSource
    Local $callback = DllCallbackRegister('__Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;str')
    Local $ptr = DllCallbackGetPtr($callback)
    Local $DllKernel32 = DllOpen('kernel32.dll')
    __ProgressCreate($aMFC)
    $aMFC[9] = TimerInit()
    For $i = 1 To $aSource[0]
    $sArray = ''
    For $j = 0 To 11
    $sArray &= $aMFC[$j] & ';'
    Next
    $sFile = StringMid($aSource[$i], StringInStr($aSource[$i], '\', 0, -1) + 1)
    If $sSourcePath <> '' Then
    $sNewFolder = StringTrimLeft(StringLeft($aSource[$i], StringInStr($aSource[$i], '\', 0, -1)), StringLen($sSourcePath))
    If Not FileExists($sDestPath & $sNewFolder) Then
    If Not DirCreate($sDestPath & $sNewFolder) Then Return SetError(3, 0, 0)
    EndIf
    EndIf
    If $sFile = '' Then ContinueLoop
    $k = 0
    While $bOverWrite = False And FileExists($sDestPath & $sNewFolder & $sFile)
    $k += 1
    $sFile = $sPreFix & $k & "_" & StringMid($aSource[$i], StringInStr($aSource[$i], '\', 0, -1) + 1)
    WEnd
    $aReturn[$i] = $sDestPath & $sNewFolder & $sFile
    $sShowSource = StringRegExpReplace($aSource[$i], '(.{15})(.*)(.{35})', '$1' & '[...]' & '$3')
    GUICtrlSetData($aMFC[1], 'Kopiere Datei ' & @CRLF & '"' & $sShowSource & '"' & @CRLF & 'nach: "' & $sShowDest & '"')
    $ret = DllCall($DllKernel32, 'int', 'CopyFileExA', 'str', $aSource[$i], 'str', $aReturn[$i], 'ptr', $ptr, 'str', $sArray, 'int', 0, 'int', 0)
    ;~ ConsoleWrite('Return: ' & $ret[0] & @LF)
    If $ret[0] = 0 Then $aMFC[10] = True
    $aMFC[8] += FileGetSize($aSource[$i])
    Next
    DllClose($DllKernel32)
    DllCallbackFree($callback)
    GUIDelete($aMFC[0])
    DllClose($aMFC[11])
    Opt('GUICloseOnESC', $oldGUICloseOnESC)
    Return $aReturn
    EndFunc ;==>_MultiFileCopy

    [/autoit] [autoit][/autoit] [autoit]

    Func __Progress($FileSize, $BytesTransferred, $StreamSize, $StreamBytesTransferred, $dwStreamNumber, $dwCallbackReason, $hSourceFile, $hDestinationFile, $lpData)
    Local $aSplit = StringSplit(StringTrimRight($lpData, 1), ";")
    If $aSplit[11] = 'True' Then Return 1
    Local $pos = GUIGetCursorInfo($aSplit[1])
    If _IsPressed('1B', Int($aSplit[12])) Then Return 1
    If _IsPressed('01', Int($aSplit[12])) And ($pos[4] = Int($aSplit[7])) Then Return 1
    Local $sPercent = Round($BytesTransferred / $FileSize * 100, 0), $iTime, $iTotalTime, $iTransferRate
    Local $sPercentAll = Round(($aSplit[9] + $BytesTransferred) / $aSplit[8] * 100, 0)
    $iTime = TimerDiff($aSplit[10])
    $iTotalTime = Ceiling($iTime / 1000 / ($sPercentAll + 0.1) * 100)
    $iTransferRate = _StringAddThousandsSep(Int($aSplit[8] / $iTotalTime / 1000), '.', ',')
    GUICtrlSetData($aSplit[3], $sPercent & ' %')
    GUICtrlSetData($aSplit[5], $sPercent)
    GUICtrlSetData($aSplit[4], $sPercentAll & ' % Zeit: ' & Int($iTime / 1000) & '/' & $iTotalTime & ' s (' & $iTransferRate & ' KB/s)')
    GUICtrlSetData($aSplit[6], $sPercentAll)
    EndFunc ;==>__Progress

    [/autoit] [autoit][/autoit] [autoit]

    Func __ProgressCreate(ByRef $aMFC)
    If Not IsDeclared('WS_POPUPWINDOW') Then Local Const $WS_POPUPWINDOW = 0x80880000
    If Not IsDeclared('WS_EX_TOPMOST') Then Local Const $WS_EX_TOPMOST = 0x00000008
    If Not IsDeclared('WS_EX_TOOLWINDOW') Then Local Const $WS_EX_TOOLWINDOW = 0x00000080
    If Not IsDeclared('WS_EX_COMPOSITED') Then Local Const $WS_EX_COMPOSITED = 0x02000000
    $aMFC[0] = GUICreate('MultiFileCopy', 480, 220, -1, -1, $WS_POPUPWINDOW, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_COMPOSITED))
    $aMFC[1] = GUICtrlCreateLabel('', 10, 10, 460, 65)
    GUICtrlSetFont(-1, 10, 400, 0, 'Courier New')
    GUICtrlCreateLabel('Datei:', 10, 83, 60, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[2] = GUICtrlCreateLabel('0 %', 80, 83, 390, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[4] = GUICtrlCreateProgress(10, 100, 460, 20)
    GUICtrlCreateLabel('Gesamt:', 10, 133, 60, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[3] = GUICtrlCreateLabel('0 %', 80, 133, 390, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[5] = GUICtrlCreateProgress(10, 150, 460, 20)
    $aMFC[6] = GUICtrlCreateButton('Abbrechen', 200, 185, 75, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUISetState()
    EndFunc ;==>__ProgressCreate

    [/autoit] [autoit][/autoit] [autoit]

    ;==================================================================================================
    ; Function Name: _GetFilesFolder_Rekursiv($sPath [, $sExt='*' [, $iDir=-1 [, $iRetType=0 ,[$sDelim='0']]]])
    ; Description: Rekursive Auflistung von Dateien und/oder Ordnern
    ; Anpassung: Verzeichnisgröße ermitteln für _MultiFileCopy ($strSize)
    ; Parameter(s): $sPath der Basispfad für die Auflistung ('.' -aktueller Pfad, '..' -Parentpfad)
    ; $sExt Erweiterung für Dateiauswahl '*' oder -1 für alle (Standard)
    ; $iDir -1 Dateien+Ordner(Standard), 0 nur Dateien, 1 nur Ordner
    ; optional: $iRetType 0 gibt Array, 1 gibt String zurück
    ; optional: $sDelim legt Trennzeichen für Stringrückgabe fest
    ; 0 -@CRLF (Standard) 1 -@CR 2 -@LF 3 -';' 4 -'|'
    ; Return Value(s): Array (Standard) od. String mit den gefundenen Pfaden der Dateien und/oder Ordner
    ; Array[0] enthält die Anzahl der gefundenen Dateien/Ordner
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _GetFilesFolder_Rekursiv($sPath, $sExt='*', $iDir=-1, $iRetType=0, $sDelim='0')
    Global $oFSO = ObjCreate('Scripting.FileSystemObject')
    Global $strFiles = ''
    Switch $sDelim
    Case '1'
    $sDelim = @CR
    Case '2'
    $sDelim = @LF
    Case '3'
    $sDelim = ';'
    Case '4'
    $sDelim = '|'
    Case Else
    $sDelim = @CRLF
    EndSwitch
    If ($iRetType < 0) Or ($iRetType > 1) Then $iRetType = 0
    If $sExt = -1 Then $sExt = '*'
    If ($iDir < -1) Or ($iDir > 1) Then $iDir = -1
    _ShowSubFolders($oFSO.GetFolder($sPath),$sExt,$iDir,$sDelim)
    If $iRetType = 0 Then
    Local $aOut
    $aOut = StringSplit(StringTrimRight($strFiles, StringLen($sDelim)), $sDelim, 1)
    If $aOut[1] = '' Then
    ReDim $aOut[1]
    $aOut[0] = 0
    EndIf
    Return $aOut
    Else
    Return StringTrimRight($strFiles, StringLen($sDelim))
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _ShowSubFolders($Folder, $Ext='*', $Dir=-1, $Delim=@CRLF)
    If Not IsDeclared("strFiles") Then Global $strFiles = ''
    If ($Dir = -1) Or ($Dir = 0) Then
    For $file In $Folder.Files
    If $Ext <> '*' Then
    If StringRight($file.Name, StringLen($Ext)) = $Ext Then
    $strSize += $file.size
    $strFiles &= $file.Path & $Delim
    EndIf
    Else
    $strSize += $file.size
    $strFiles &= $file.Path & $Delim
    EndIf
    Next
    EndIf
    For $Subfolder In $Folder.SubFolders
    If ($Dir = -1) Or ($Dir = 1) Then $strFiles &= $Subfolder.Path & '\' & $Delim
    _ShowSubFolders($Subfolder, $Ext, $Dir, $Delim)
    Next
    EndFunc

    [/autoit]

    Die klappt bei mir immer ! ;)