Imbecility Posted March 23, 2015 Share Posted March 23, 2015 Hello, I am transitioning from AutoHotkey to AutoIt and am looking for a nudge in the right direction with regard to looping through files and folders. What I would like to do is create a delimited list of certain attributes (filename, path, extension, size, last modified) about all files in network drives. In AutoHotkey I can use "Loop, FilePattern" to go through every file and folder and pull all the information I need. How can I go about doing this efficiently in AutoIt? From what I've learned so far, it appears I'll need to use "FileListToArray" to create an array of filepaths, then loop through the entire array, using "FileGet . . ." for each element. Is there a better way or am I on the right track? Please be kind as this is my first post. Thank you! Link to comment Share on other sites More sharing options...
water Posted March 23, 2015 Share Posted March 23, 2015 Welcome to AutoIt and the forum! I would start with _FileListToArrayRec to recursively list files and/or folders. Then use FileGetAttrib to retrieve the attributes. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
Imbecility Posted March 25, 2015 Author Share Posted March 25, 2015 Thank you water. My intent is to make a database of all network files, with "Filename", "Extension", "Filepath", "Mod. Date", and "Size (kb)" headings. My code for doing just my desktop is below, but I'm a bit disappointed in how much time it takes to complete (~25 seconds). FYI, I have 5,208 files on my desktop and in subfolders. Is there anything I can do/change to make it run more quickly? #include <Array.au3> #include <File.au3> $aFileList = _FileListToArrayRec(@DesktopDir,"*",0,1,0,2) Local $aDBList[0][5] Local $sDrive = "", $sDir = "", $sFilename = "", $sExtension = "" _ArrayAdd($aDBList,$aFileList[0]) For $nCt = 1 To $aFileList[0] $sFileSize = Ceiling(FileGetSize($aFileList[$nCt])/1024) $sFileModDate = FileGetTime($aFileList[$nCt],0,1) _PathSplit($aFileList[$nCt], $sDrive, $sDir, $sFilename, $sExtension) $sDBListRow = $sFilename & $sExtension & "|" & $sExtension & "|" & $sDrive & $sDir & "|" & $sFileModDate & "|" & $sFileSize _ArrayAdd($aDBList,$sDBListRow) Next _ArrayDisplay($aDBList) The output doesn't necessarily need to be an array; a delimited text file would suffice as well. Thank you! Link to comment Share on other sites More sharing options...
Solution mikell Posted March 25, 2015 Solution Share Posted March 25, 2015 This is a bit faster #include <Array.au3> #include <File.au3> $aFileList = _FileListToArrayRec(@DesktopDir,"*",0,1,0,2) Local $aDBList[100000][5] Local $sDrive = "", $sDir = "", $sFilename = "", $sExtension = "" $aDBList[0][0] = $aFileList[0] For $nCt = 1 To $aFileList[0] $sFileSize = Ceiling(FileGetSize($aFileList[$nCt])/1024) $sFileModDate = FileGetTime($aFileList[$nCt],0,1) _PathSplit($aFileList[$nCt], $sDrive, $sDir, $sFilename, $sExtension) $aDBList[$nCt][0] = $sFilename & $sExtension $aDBList[$nCt][1] = $sExtension $aDBList[$nCt][2] = $sDrive & $sDir $aDBList[$nCt][3] = $sFileModDate $aDBList[$nCt][4] = $sFileSize Next Redim $aDBList[$nCt][5] _ArrayDisplay($aDBList) Link to comment Share on other sites More sharing options...
Imbecility Posted March 26, 2015 Author Share Posted March 26, 2015 This is a bit faster Wow, that is much faster (~2 sec. compared to ~25 sec). Thank you very kindly! Link to comment Share on other sites More sharing options...
mikell Posted March 26, 2015 Share Posted March 26, 2015 You're welcome FYI the _Array* funcs are slow and should be avoided in case of large number of entries e.g. _ArrayAdd() does StringSplit and Redim at each pass, while the code above Redims only once Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 26, 2015 Moderators Share Posted March 26, 2015 Imbecility,The Recursion tutorial in the Wiki shows in the final example how best to fill an array whose final size is not known. Basically you keep doubling it in size when you fill it. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
mikell Posted March 26, 2015 Share Posted March 26, 2015 Redimming only once is still better Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 26, 2015 Moderators Share Posted March 26, 2015 mikell,If you initially create the array with an enormous number of elements that may well be possible, but then you could run into memory problems if it was truly gigantic and you had a lot of other data to store. Personally I prefer a reasonable initial size followed by doubling when necessary. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
jguinch Posted March 26, 2015 Share Posted March 26, 2015 @mikell : I don't understand why you did not use Local $aDBList[$aFileList[0]][5] ??? Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
mikell Posted March 26, 2015 Share Posted March 26, 2015 (edited) Should be Local $aDBList[$aFileList[0]+1][5] but of course you are right This is a too-quickly-done-script oversight Edit Funny, nobody but you saw this Edited March 26, 2015 by mikell Link to comment Share on other sites More sharing options...
Imbecility Posted March 26, 2015 Author Share Posted March 26, 2015 Should be Local $aDBList[$aFileList[0]+1][5] but of course you are right This is a too-quickly-done-script oversight Edit Funny, nobody but you saw this I had actually already editted my code to be like this, as my next test was my entire C-drive and the 100,000 amount wasn't high enough. I am extremely pleased with the results! I had been using Autohotkey (an still am until I convert the code over) to create local and network databases. It took ~1h:20m to process just under 200,000 files in Autohotkey, but just under 30s for just over 200,000 files in AutoIt - that's 160x faster... I'm sure my Autohotkey code could have been optimized for efficiency, but it appears there will be no need to pursue that! Needless to say, I'm now a believer! Link to comment Share on other sites More sharing options...
jguinch Posted March 26, 2015 Share Posted March 26, 2015 @Imbecility : with Melba's suggestion in #7, you could make your own function, faster (2 times faster, if it is not more) Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF 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