lewwy Posted March 2, 2010 Share Posted March 2, 2010 Hi All, I'm having a bit of trouble with my script at the moment. The function that this is trying to accomplish is being able to copy a directory with exceptions, so if the file is an mp3 wma avi or whatever then it wont copy. Heres the func: expandcollapse popupFunc CopyFolder($SourceFolder, $DestinationDir) If Not FileExists($DestinationDir) Then DirCreate($DestinationDir) Local $Search = 0 Local $File = 0 Local $FileAttributes = 0 $FullFilePath = "" $arraycounter = 0 $Search = FileFindFirstFile($SourceFolder & "\*.*") While 1 $ArrayCounter = $ArrayCounter + 1 ReDim $FileListing[$FileListing[0]+$ArrayCounter] If $Search = -1 Then ExitLoop EndIf $File = FileFindNextFile($Search) If @error Then ExitLoop $FullFilePath = $SourceFolder & "\" & $File $FileAttributes = FileGetAttrib($FullFilePath) If StringInStr($FileAttributes,"D") Then $RefinedFolderName = $FullFilePath ;msgbox(0, "hm", "after setting $refinedfoldername to the same as $fullfilepath, its value is " & $RefinedFolderName) ;$RefinedFolderNamePosition = StringInStr($RefinedFolderName, "\", 0, -1) $RefinedFolderName = StringTrimLeft($RefinedFolderName, 12) ;msgbox(0, "hm", "after trimming left 12, its value is " & $RefinedFolderName) $RefinedFolderName = $RefinedFolderName & "\" ;msgbox(0, "hm", "after adding a slash onto $Refinedfoldername, its value is " & $RefinedFolderName) ;msgbox(0, "found a folder", "found a \ at " & $RefinedFolderNamePosition & " for string " & $RefinedFolderName) ;_FileWriteLog("log.txt", "Found a directory called " & $RefinedFolderName & " which we are copying to " & $DestinationDir & $RefinedFolderName) ;DirCreate($DestinationDir & $RefinedFolderName) CopyFolder($FullFilePath, $DestinationDir & "\" & $RefinedFolderName) Else ;LogFile($FullFilePath) ;_FileWriteLog("log.txt", "Found a file called " & $FullFilePath & " which we are copying to " & $DestinationDir & "\" & $RefinedFolderName) Select Case StringInStr($FullFilePath, ".mp3") > 0 _FileWriteLog($BackupLocation & "\log.txt", "Not copying " & $FullFilePath & " because it is an MP3 file and is an exception") ;msgbox(0, "mp3", "found a \ at " & $RefinedFolderNamePosition & " for string " & $RefinedFolderName) Case StringInStr($FullFilePath, ".wma") > 0 _FileWriteLog($BackupLocation & "\log.txt", "Not copying " & $FullFilePath & " because it is an WMA file and is an exception") Case StringInStr($FullFilePath, ".avi") > 0 _FileWriteLog($BackupLocation & "\log.txt", "Not copying " & $FullFilePath & " because it is an AVI file and is an exception") Case Else FileCopy($FullFilePath, $DestinationDir, 9) _FileWriteLog($BackupLocation & "\log.txt","Copying " & $FullFilePath &" to " & $DestinationDir) ;msgbox(0, "casing else", "found a \ at " & $RefinedFolderNamePosition & " for string " & $RefinedFolderName) EndSelect EndIf ;msgbox(0, "lol wat", "copying " & $FullFilePath & " to " & $DestinationDir & $RefinedFolderName) ;msgbox(0, "", $FullFilePath) WEnd FileClose($Search) EndFunc I've been nutting away at this for quite some time now...so its probably a bit overdone. If anyone could help I would be forever endebted... Additionally sorry for the dry reaching you're probably getting from reading my code Link to comment Share on other sites More sharing options...
omikron48 Posted March 2, 2010 Share Posted March 2, 2010 I made a stack based search function and PsaltyDS made a recursive version of it. You can just modify the section of the code which handles the file matching to get the type of matching behavior you need.The thread is here. Link to comment Share on other sites More sharing options...
lewwy Posted March 3, 2010 Author Share Posted March 3, 2010 I made a stack based search function and PsaltyDS made a recursive version of it. You can just modify the section of the code which handles the file matching to get the type of matching behavior you need.The thread is here.Thanks for that man...but it doesnt recurse? arraydisplay just shows the root directory. Link to comment Share on other sites More sharing options...
omikron48 Posted March 3, 2010 Share Posted March 3, 2010 Look closely. PsaltyDS' and mine also provide search results for subfolders depending on the parameters you provide it. Link to comment Share on other sites More sharing options...
lewwy Posted March 3, 2010 Author Share Posted March 3, 2010 Look closely. PsaltyDS' and mine also provide search results for subfolders depending on the parameters you provide it. Setting depth to -1 yields the same results...heres the code expandcollapse popup#include <Array.au3> Dim $array Opt("MustDeclareVars", 1) ;Put somewhere at the start of your script ;### STACK DEFINITION ### Global $RESULT_MAX = 0xFFF ;maximum size of the returned array Global $STACK_MAX = 0xFFF ;maximum size of the search stack Global $STACK[$STACK_MAX] ;the search stack $STACK[0] = 0 ;stack element counter Func _Push($var) ;Utility function. DO NOT CALL If $STACK[0] < $STACK_MAX - 1 Then $STACK[0] += 1 $STACK[$STACK[0]] = $var Else Return 1 EndIf Return 0 EndFunc Func _Pop() ;Utility function. DO NOT CALL If $STACK[0] > 0 Then $STACK[0] -= 1 Return $STACK[$STACK[0] + 1] Else SetError(1) EndIf Return 0 EndFunc ;### END STACK DEFINITION ### Global $start = TimerInit() Global $result = _Search("c:\", "*.*", false, "", "", -1) Global $time = TimerDiff($start) _ArrayDisplay($result, "Time = " & _ConvertTime($time)) Func _ConvertTime($millis) Local $days = Int($millis / 86400000) $millis -= $days * 86400000 Local $hours = Int($millis / 3600000) $millis -= $hours * 3600000 Local $minutes = Int($millis / 60000) $millis -= $minutes * 60000 Local $seconds = Int($millis / 1000) $millis -= $seconds * 1000 Local $result = "" If $days > 0 Then $result &= $days & "d:" EndIf If $hours > 0 Then $result &= StringFormat("%.2d", $hours) & "h:" EndIf If $minutes > 0 Then $result &= StringFormat("%.2d", $minutes) & "m:" EndIf If $seconds > 0 Then $result &= StringFormat("%.2d", $seconds) Else $result &= "00" EndIf $result &= "." & StringFormat("%.3d", $millis) & "s" Return $result EndFunc ;### SEARCH FUNCTION ### ;Returns array containing full path of matched files, with [0] containing the count of returned elements. ; ;$path = start location of search ; ;$filter = expression to use for file matching (e.g. *.txt) ; ;$directories = set to true if directories are to be included in the search results ; Default set to True ; ;$fExclude = attributes (look at FileGetAttrib) used to exclude files from search (e.g. if you want to skip read-only or hidden files) ; Default set to empty string ; ;$dExclude = attributes (look at FileGetAttrib) used to exclude folder from recursive search (e.g. if you want to skip searching system or hidden folders) ; Default set to empty string ; ;$depth = folder depth to limit search ; Default set to -1 ; ; Values: ; 0 -> current folder only ; n -> search up to n folders deep ; -1 -> search in all subfolders ; _Search("C:\*.*", "*.*", 1, "*.mp3", "", -1) Func _Search($path, $filter, $directories = True, $fExclude = "", $dExclude = "", $depth = -1) ;check directory exists If FileExists($path) Then ;add "\" to end of path value if needed If StringCompare(StringRight($path, 1), "\") <> 0 Then $path &= "\" EndIf Local $result = "" Local $search, $fname, $attrib Local $array[2], $temp[2] $array[0] = $path $array[1] = $depth ;push initial search path to stack _Push($array) While 1 ;pop next search path from stack $array = _Pop() ;exit if empty stack If @error == 1 Then ExitLoop EndIf ;search contents of current directory $search = FileFindFirstFile($array[0] & $filter) If $search <> -1 Then While 1 $fname = FileFindNextFile($search) If @error == 1 Then ExitLoop EndIf ;skip processing if directory is not included in search results If @extended == 1 And Not $directories Then ContinueLoop EndIf ;add file to results if it is not excluded from search ; $attrib = FileGetAttrib($fname) ; If _IsIncluded($attrib, $fExclude) Then $result &= $array[0] & $fname & "|" ; EndIf WEnd FileClose($search) EndIf ;process subdirectories if within depth parameter If $array[1] <> 0 Then ;add subdirectories to stack if not excluded from search $search = FileFindFirstFile($array[0] & "*") While 1 $fname = FileFindNextFile($search) If @error == 1 Then ExitLoop EndIf ;add directory to stack if not excluded from search If @extended == 1 Then ; $attrib = FileGetAttrib($fname) ; If _IsIncluded($attrib, $dExclude) Then $temp[0] = $array[0] & $fname & "\" $temp[1] = $array[1] - 1 _Push($temp) ; EndIf EndIf WEnd FileClose($search) EndIf WEnd ;create return array If StringCompare(StringRight($result, 1), "|") == 0 Then $result = StringTrimRight($result, 1) $result = StringSplit($result, "|") Else $result = 0 EndIf Return $result Else SetError(1, 0, 0) EndIf EndFunc ;Func _IsIncluded($attrib, $exclude) ;Utility function. DO NOT CALL ; For $i = 1 To StringLen($exclude) ; If StringInStr($attrib, StringMid($exclude, $i, 1)) <> 0 Then ; Return False ; EndIf ; Next ; Return True ;EndFunc ;### END SEARCH FUNCTION ### ;msgbox(0, "wat", "cake") _ArrayDisplay($array) ;msgbox(0, "wat", "cake") Am I just being dense D: Link to comment Share on other sites More sharing options...
omikron48 Posted March 3, 2010 Share Posted March 3, 2010 (edited) You should've read more, then you'd have found that there is corrected code at my latest post in that thread. Here's one that works for me. it lists the contents of the C:\ drive. expandcollapse popup#include <Array.au3> Opt("MustDeclareVars", 1) ;Put somewhere at the start of your script ;### STACK DEFINITION ### Global $STACK_MAX = 1;0xFF ;maximum size of the search stack Global $STACK[$STACK_MAX] ;the search stack $STACK[0] = 0 ;stack element counter Func _Push($var) ;Utility function. DO NOT CALL If $STACK[0] > $STACK_MAX - 2 Then $STACK_MAX *= 2 ReDim $STACK[$STACK_MAX] EndIf $STACK[0] += 1 $STACK[$STACK[0]] = $var Return 1 EndFunc Func _Pop() ;Utility function. DO NOT CALL If $STACK[0] > 0 Then $STACK[0] -= 1 Return $STACK[$STACK[0] + 1] Else SetError(1) EndIf Return 0 EndFunc ;### END STACK DEFINITION ### Global $result = _Search("c:\", "*.*", false, -1) _ArrayDisplay($result, "Results") ;### SEARCH FUNCTION ### ;Returns array containing full path of matched files, with [0] containing the count of returned elements. ; ;PARAMETERS: ; ;$path = start location of search ; ;$filter = expression to use for file matching (e.g. *.txt) ; ;$directories = set to true if directories are to be included in the search results ; Default set to True ; ;$depth = folder depth to limit search ; Default set to -1 ; ; Values: ; 0 -> current folder only ; n -> search up to n folders deep ; -1 -> search in all subfolders ; ;RETURN VALUE: ; ;Success: Array of files and folders matching the search parameter. ; [0] contains the count of matched elements. ; matched folders end with "\" ; ;Failure: Returns 0. ; Sets @error to: ; 1 -> $path does not exist. ; 2 -> No matches found. ; Func _Search($path, $filter, $directories = True, $depth = -1) ;check directory exists If FileExists($path) Then ;add "\" to end of path value if needed If StringCompare(StringRight($path, 1), "\") <> 0 Then $path &= "\" EndIf Local $result = "" Local $search, $fname, $attrib Local $array[2], $temp[2] $array[0] = $path $array[1] = $depth ;push initial search path to stack _Push($array) While 1 ;pop next search path from stack $array = _Pop() ;exit if empty stack If @error == 1 Then ExitLoop EndIf ;search contents of current directory $search = FileFindFirstFile($array[0] & $filter) If $search <> -1 Then While 1 $fname = FileFindNextFile($search) If @error == 1 Then ExitLoop EndIf ;skip processing if directory is not included in search results If @extended == 1 Then If Not $directories Then ContinueLoop Else $fname &= "\" EndIf EndIf ;add file to results $result &= $array[0] & $fname & "|" WEnd FileClose($search) EndIf ;process subdirectories if within depth parameter If $array[1] <> 0 Then ;add subdirectories to stack if not excluded from search $search = FileFindFirstFile($array[0] & "*") While 1 $fname = FileFindNextFile($search) If @error == 1 Then ExitLoop EndIf ;add directory to stack $temp[0] = $array[0] & $fname & "\" $temp[1] = $array[1] - 1 _Push($temp) WEnd FileClose($search) EndIf WEnd ;create return array If StringCompare(StringRight($result, 1), "|") == 0 Then $result = StringTrimRight($result, 1) $result = StringSplit($result, "|") Else $result = 0 SetError(2, 0, 0) EndIf Return $result Else SetError(1, 0, 0) EndIf EndFunc ;### END SEARCH FUNCTION ### EDIT: The script you posted worked fine for me. I got the list of files in C:\. EDIT2: Removed unneeded code from script. Edited March 3, 2010 by omikron48 Link to comment Share on other sites More sharing options...
lewwy Posted March 3, 2010 Author Share Posted March 3, 2010 You should've read more, then you'd have found that there is corrected code at my latest post in that thread.Here's one that works for me. it lists the contents of the C:\ drive.EDIT: The script you posted worked fine for me. I got the list of files in C:\.EDIT2: Removed unneeded code from script.<3 you omikron...probably be a bit better if I were a girl saying that tho. I'll go give this a test and see how it goes. Link to comment Share on other sites More sharing options...
omikron48 Posted March 4, 2010 Share Posted March 4, 2010 (edited) Keep in mind, you'd still need to modify the code to get the matching behavior that you want.I'd suggest using StringRegExp OR a combination of StringRight and StringCompare to test whether the filename you are processing ends with a certain file extension.Can't help much with regular expressions since I don't get it much myself yet.If StringCompare(StringRight($filename, 4), ".mp3") Then ;$filename is doesn't end in ".mp3" EndIf Edited March 4, 2010 by omikron48 Link to comment Share on other sites More sharing options...
lewwy Posted March 4, 2010 Author Share Posted March 4, 2010 (edited) Keep in mind, you'd still need to modify the code to get the matching behavior that you want. I'd suggest using StringRegExp OR a combination of StringRight and StringCompare to test whether the filename you are processing ends with a certain file extension. Can't help much with regular expressions since I don't get it much myself yet. If StringCompare(StringRight($filename, 4), ".mp3") Then ;$filename is doesn't end in ".mp3" EndIf Was thinking more along the lines of reading the entire directory to the array then when it comes to copying do something like this Select Case StringInStr($array[$counter], "*.mp3" ; dont copy Case StringInStr($array[$counter], "*.avi" ; dont copy Case StringInStr($array[$counter], "*.wma" ; dont copy Case Else FileCopy(blah blah blah) EDIT: Problem with this being is that the $result is declared locally...moving that out to a dim so another function doesn't seem to work either. How would I read from the $result array in other functions? Edited March 4, 2010 by lewwy Link to comment Share on other sites More sharing options...
omikron48 Posted March 4, 2010 Share Posted March 4, 2010 Either store the return from _Search into a Global variable or pass the result into the other function. Just using StringInStr isn't recommendable since there is nothing stopping anybody from making a folder with the name "music.mp3". It's a legal folder name. Anything contained there will match for StringInStr($array[$counter], "*.mp3"). Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now