mikell Posted May 9, 2010 Posted May 9, 2010 Hello Could't find this anywhere... In a ListBox or Edit which displays a list of files, how to make this list sort them by size (biggest above, smallest below) ? Many thanks to any helper
DW1 Posted May 9, 2010 Posted May 9, 2010 Maybe there is a simpler way, but the way I would go about it is get all the files in an array and then get all the filesizes in an array with the filenames. Now we can just sort the array based on the filesize, then display the contents anywhere. Something like this: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <array.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 600, 450) $Edit1 = GUICtrlCreateEdit("", 300, 0, 300, 400) GUICtrlSetData(-1, "") $List1 = GUICtrlCreateList("", 0, 0, 300, 400, BitOR($WS_BORDER, $WS_VSCROLL)); Set default style with the exception of $LBS_SORT, which forces alphabetical sorting $Bfolder = GUICtrlCreateButton("Select Folder To Read File In From", 0, 400, 600, 50) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Bfolder $SFolder = FileSelectFolder("Select Folder", "") If $SFolder <> '' Then If StringRight($SFolder, 1) <> '\' Then $SFolder &= '\'; Add trailing slash if it isn't there $AFiles = _FileSearch($SFolder & '*.*', 0, 0, 1, 0) Else Dim $AFiles[1] $AFiles[0] = 0 EndIf If $AFiles[0] <> 0 Then Dim $ASize[$AFiles[0]][2] For $a = 1 To $AFiles[0] $ASize[$a - 1][0] = FileGetSize($AFiles[$a]) $ASize[$a - 1][1] = $AFiles[$a] Next _ArraySort($ASize) ;For Edit $SEditString = '' For $a = 0 To UBound($ASize) - 1 $SEditString &= $ASize[$a][1] If $a <> UBound($ASize) - 1 Then $SEditString &= @CRLF Next GUICtrlSetData($Edit1, $SEditString) ;For List $SListString = '' For $a = 0 To UBound($ASize) - 1 $SListString &= $ASize[$a][1] If $a <> UBound($ASize) - 1 Then $SListString &= '|' Next GUICtrlSetData($list1, ''); Clear any old data GUICtrlSetData($List1, $SListString) EndIf EndSwitch WEnd ; ---------File Search Functions---------- ; _FileSearch( "Path and Mask", <$nOption>, <$cpusaver>, <$dirfilter>, <$filefilter>) ; ;----PARAMETERS----- ;$nOption - <Optional (0 - normal, 1- recursive)> ;$cpusaver - <Optional (0 - normal, 1 - CPU Friendly, but Slower)> ;$dirfilter - <Optional (0 - list directories, 1 - filter out directories)> ;$filefilter- <Optional (0 - list files, 1 - filter out files)> ; ;----RETURN----- ; Returns array. Either Array of files (full path) where... ; Array[0] is number of files. ; Array[0] = 0 if nothing found. ; EXAMPLE USAGE ;-------------------------------------------- ;~ #include<array.au3> ;~ $a = _FileSearch("C:\*.*", 1, 0, 0, 0) ;~ _ArrayDisplay($a) ;-------------------------------------------- Func _FileSearch($szMask, $nOption = 0, $cpusaver = 0, $dirfilter = 0, $filefilter = 0) $szRoot = "" $hFile = 0 $szBuffer = "" $szReturn = "" $szPathList = "*" Dim $aNULL[1] If Not StringInStr($szMask, "\") Then $szRoot = @ScriptDir & "\" Else While StringInStr($szMask, "\") $szRoot = $szRoot & StringLeft($szMask, StringInStr($szMask, "\")) $szMask = StringTrimLeft($szMask, StringInStr($szMask, "\")) WEnd EndIf If $nOption = 0 Then _FileSearchUtil($szRoot, $szMask, $szReturn, $cpusaver, $dirfilter, $filefilter) Else While 1 $hFile = FileFindFirstFile($szRoot & "*.*") If $hFile >= 0 Then $szBuffer = FileFindNextFile($hFile) While Not @error If $szBuffer <> "." And $szBuffer <> ".." And _ StringInStr(FileGetAttrib($szRoot & $szBuffer), "D") Then _ $szPathList = $szPathList & $szRoot & $szBuffer & "*" $szBuffer = FileFindNextFile($hFile) WEnd FileClose($hFile) EndIf _FileSearchUtil($szRoot, $szMask, $szReturn, $cpusaver, $dirfilter, $filefilter) If $szPathList == "*" Then ExitLoop $szPathList = StringTrimLeft($szPathList, 1) $szRoot = StringLeft($szPathList, StringInStr($szPathList, "*") - 1) & "\" $szPathList = StringTrimLeft($szPathList, StringInStr($szPathList, "*") - 1) WEnd EndIf If $szReturn = "" Then $aNULL[0] = 0 Return $aNULL Else Return StringSplit(StringTrimRight($szReturn, 1), "*") EndIf EndFunc ;==>_FileSearch Func _FileSearchUtil(ByRef $ROOT, ByRef $MASK, ByRef $RETURN, $cpusaver, $dirfilter, $filefilter) $hFile = FileFindFirstFile($ROOT & $MASK) If $hFile >= 0 Then $szBuffer = FileFindNextFile($hFile) While Not @error If $cpusaver = 1 Then Sleep(1) ;OPTIONAL FOR CPU SAKE If $szBuffer <> "." And $szBuffer <> ".." Then If StringInStr(FileGetAttrib($ROOT & $szBuffer), "D") Then If $dirfilter = 0 Then $RETURN = $RETURN & $ROOT & $szBuffer & "*" Else If $filefilter = 0 Then $RETURN = $RETURN & $ROOT & $szBuffer & "*" EndIf EndIf $szBuffer = FileFindNextFile($hFile) WEnd FileClose($hFile) EndIf EndFunc ;==>_FileSearchUtil AutoIt3 Online Help
mikell Posted May 10, 2010 Author Posted May 10, 2010 (edited) Thank you !I can't see an easier solution than using your 2-dimensional arrayI didn't know this _FileSearch function, isn't it possible to get the same result with the usual UDF _FileListToArray included in array.au3 File.au3 ? This should make the script simpler Edited May 10, 2010 by mikell
DW1 Posted May 10, 2010 Posted May 10, 2010 Yeah, you should be able to do the same thing with _FileListToArray, I have just been using that _FileSearch function for quite some time now. I like that I can make it recursive with a switch, and calm the CPU usage with a switch. AutoIt3 Online Help
mikell Posted May 10, 2010 Author Posted May 10, 2010 I like this _FileSearch function Til now I used this _FindFiles, I found it somewhere in the forum #Include <Array.au3> _FindFiles(@scriptdir, '*') Func _FindFiles($sRoot, $sFile) Local $FileList $FileList = _FileListToArray($sRoot, $sFile, 2) If Not @error Then _ArrayDisplay($FileList) ;For $i = 1 To $FileList[0] ; FileWriteLine ($txt, $sRoot & '\' & $FileList[$i]) ;Next EndIf $FileList = _FileListToArray($sRoot, '*', 2) If Not @error Then For $i = 1 To $FileList[0] _FindFiles($sRoot & '\' & $FileList[$i], $sFile) Next EndIf EndFunc ;==>_FindFiles Recursive search too, and very easy to use
omikron48 Posted May 11, 2010 Posted May 11, 2010 Here's a faster file search function: expandcollapse popup;### 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) ; ;$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 ; ;$directories = set to true if directories are to be included in the search results ; Default set to True ; ;$files = set to true if files are to be included in the search results ; Default set to True ; ;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 = "*", $depth = -1, $directories = True, $files = True) ;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 = "" ;conduct search _SearchUtil($result, $path, $filter, $depth, $directories, $files) ;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 Func _SearchUtil(ByRef $result, $path, $filter, $depth, $directories, $files) Local $search = FileFindFirstFile($path & $filter) Local $fname If $search <> -1 Then While 1 $fname = FileFindNextFile($search) If @error == 1 Then ExitLoop EndIf ;skip processing if directory/file is not included in search results If @extended == 1 Then If Not $directories Then ContinueLoop Else $fname &= "\" EndIf Else If Not $files Then ContinueLoop EndIf EndIf ;add file to results $result &= $path & $fname & "|" WEnd FileClose($search) EndIf ;process subdirectories if within depth parameter If $depth <> 0 Then $search = FileFindFirstFile($path & "*") While 1 $fname = FileFindNextFile($search) If @error == 1 Then ExitLoop EndIf ;search subdirectory If @extended == 1 Then _SearchUtil($result, $path & $fname & "\", $filter, $depth - 1, $directories, $files) EndIf WEnd FileClose($search) EndIf EndFunc ;### END SEARCH FUNCTION ###
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