Sign in to follow this  
Followers 0
KaFu

_DirGetSizeEx

23 posts in this topic

#1 ·  Posted (edited)

Did this for use with SMF. UDF _DirGetSizeEx() is using AU native functions only...

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.0.0
 Author:         KaFu
 Script Name, Version and Date: _DirGetSizeEx v04 (09-Jan-22)

 Script Function:
    _DirGetSizeEx, a replacement for DirGetSize()
    UDF using AU native functions only. Faster than DirGetSize() in the inital run on XP, slower in a repeated run, DirGetSize seems to cache the result.
    Change $Path between tests to seem what I mean.
   
    DirGetSize can not be interrupted / stopped, that's the main reason I coded this UDF

    Function returns an array
    $array[0] = Bytes
    $array[1] = File Count
    $array[2] = Folder Count

    On Vista DirGetSize seems to be much faster than on XP, thus if you're only into speed use something like:
    
    if @OSVersion <> "WIN_VISTA" Then
        $aResult = _DirGetSizeEx($Path)
    Else
        $aResult = DirGetSize($Path)
    EndIf
    
    But keep in mind, main advantage of _DirGetSizeEx is that during runtime you can easily implement a progress count or interrupt the function with
    a global variable (like I do in SMF, just define a bool something like $running = true and switch it with WM_COMMAND)

#ce ----------------------------------------------------------------------------

Dim $Path = @AppDataDir

$begin = TimerInit()
$a_DirGetSize = DirGetSize($Path, 1)
$dif_DirGetSize = round(TimerDiff($begin),0)

$begin = TimerInit()
$a_DirGetSizeEx = _DirGetSizeEx($Path)  ; <= recommended
$dif_DirGetSizeEx = round(TimerDiff($begin),0)

MsgBox(0, 'Comparison DirGetSize() vs _DirGetSizeEx', '' _
        & 'DirGetSize()' & @crlf & 'Time: ' & $dif_DirGetSize & @crlf &  'Bytes: ' & $a_DirGetSize[0] & @crlf & 'File Count: ' & $a_DirGetSize[1] & @CRLF & 'Folder Count: ' & $a_DirGetSize[2] & @CRLF & @CRLF _
        & '_DirGetSizeEx()' & @crlf & 'Time: ' & $dif_DirGetSizeEx & @crlf & 'Bytes: ' & $a_DirGetSizeEx[0] & @crlf & 'File Count: ' & $a_DirGetSizeEx[1] & @CRLF & 'Folder Count: ' & $a_DirGetSizeEx[2])

Func _DirGetSizeEx($sPath = @ScriptDir)
    Local $sSearch, $aResult[3], $aResult_sub[3]
    If StringRight($sPath, 1) <> "\" Then $sPath &= "\" ; Ensure $sPath has a trailing slash
    $sSearch = FileFindFirstFile($sPath & "*.*")
    While 1
        $sNext = FileFindNextFile($sSearch) ; check if next file can be found, otherwise exit loop
        If @error Then ExitLoop
        If StringInStr(FileGetAttrib($sPath & $sNext), "D") Then
            $aResult[2] += 1            
            $aResult_sub = _DirGetSizeEx($sPath & $sNext)
            $aResult[0] += $aResult_sub[0]
            $aResult[1] += $aResult_sub[1]
            $aResult[2] += $aResult_sub[2]
        Else
            $aResult[1] += 1
            $aResult[0] += FileGetSize($sPath & $sNext)
        EndIf
    WEnd
    FileClose($sSearch)
    Return $aResult
EndFunc   ;==>_DirGetSizeEx

Best Regards

Edited by KaFu

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Updated first post, added function using AU native functions only...

Best Regards

Edit:

Hu, DirGetSize() seems to cache the results somehow. Repeating it on a folder it will return the result much, much faster. But invoked on a directory not analyzed before, _DirGetSizeEx() is by far the fastest method of those three...

Benchmark:

DirGetSize()

Time: 21,360 ms

Filecount: 30611

Foldercount: 353

Bytes: 7,468,535,738 (6.95GB)

_DirGetSizeEx()

Time: 7,340 ms

_DirGetSizeEx_SFSO()

Time: 11,035 ms

Edited by KaFu

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

KaFu,

Sorry to tell you , but it is not working well for me. Vista Home Premium 32 SP1.

Firstly, SciTE claims that $oScriptingFileSystemObject is not declared - fixed by putting it as Global at start.

Then the script ususally goes into some form of endless loop while running your UDFs. I did try changing the order but to no avail.

Got it to run twice in about 10 attempts giving the following results:

DirGetSize = 629 and 758

DirGetSizeEx = 41198 and 39146

DirGetSize_SFSO = 16075 and 12096

I think I will stick with DirGetSize for the moment :-)

M23

Edit: Got it to work better with other paths (smaller sizes?) - but timings still favour DirGetSize -> 2 - 139 - 21 and 509 - 2887 - 1026

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Sorry to tell you , but it is not working well for me. Vista Home Premium 32 SP1.

Thanks for the feedback :)...

Firstly, SciTE claims that $oScriptingFileSystemObject is not declared - fixed by putting it as Global at start.

Yeah, that's what I feared. I guess the Scripting.FileSystemObject is part of the NET framework and thus not installed on every machine. That's also why I wrote the second UDF using AU native functions only.

Then the script ususally goes into some form of endless loop while running your UDFs. I did try changing the order but to no avail.

Can't reproduce as I only have XP with NET 3.0 available...

Got it to run twice in about 10 attempts giving the following results:

Would you be so kind to test the attached script? I cut the Scripting.FileSystemObject part, only AU native functions...

Edit: Got it to work better with other paths (smaller sizes?) - but timings still favour DirGetSize -> 2 - 139 - 21 and 509 - 2887 - 1026

Yep, I guess you tested it on the same dir twice :lmao:, that's what I meant with 'DirGetSize seems to cache the results somehow', as mine seems to be faster on every initial run to a new dir... try too run the scripts on different dirs and you'll see what I mean, run it a second time and DirGetSize will always be faster...

Here's the UDF with native functions only (guess I'll kick the SFSO version, sorry rasim :think: ).

*Updated first post

Best Regards

Edited by KaFu

Share this post


Link to post
Share on other sites

I am running WinXP SP2 and it works well for me.. Thanks! Nice li'l tidbit...

Share this post


Link to post
Share on other sites

nice udf

I like the recursion :)


Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org

Share this post


Link to post
Share on other sites

KaFu,

New version works without problems, but I still find your UDF slower (sorry!):

All tests done on previously untested folders, repeated 4 times in quick succession.

Size 2330 files - 617 folders: DirGetSize = 288 - 260 - 340 - 301, DirGetSizeEx = 1782 - 1828 - 1737 - 1796

Size 5686 files - 750 folders: DirGetSize = 203 - 203 - 178 - 191, DirGetSizeEx = 2019 - 2053 - 2137 - 2009

Size 163 files - 6 folders: DirGetSize = 31 - 3 - 3 - 3, DirGetSizeEx = 105 - 69 - 75 - 75

As far as I know I have nothing which should cause your UDF to be so slow - perhaps something in Vista? Anyone else with Vista prepared to run it and see?

I am more than happy to run more tests/versions if it will help - I feel guilty about finding the problem!

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

New version works without problems, but I still find your UDF slower (sorry!):

As far as I know I have nothing which should cause your UDF to be so slow - perhaps something in Vista? Anyone else with Vista prepared to run it and see?

Thanks for testing :lmao:... interesting, at least an advantage of vista :)? On XP my script always runs faster on initial run and slower on repeated ones. Maybe Vista has a more advanced indexing service of some kind? I don't know how DirGetSize works internally / which API's called, but I guess that's what makes the difference in runtime XP<>Vista.

Best Regards

Share this post


Link to post
Share on other sites

KaFu,

Ran the tests again this morning on the newly booted box of tricks:

DirGetSize      DirgetSizeEx

 Internal HD (C: partition) 63911 files/12129 folders

21667           41484
 4012           37333
 3830           37562
 3841           37528

 Internal HD (M: partition)163/6

76              162
 2              120
 3               65
 2               66

 Internal HD (N: partition)2645/98

352         1275
 26         1275
 27         1062
 46         1050

 Ext USB HD5 686/750

5315            1937
 188            1923
 146            1976
 153            1894

USB Stick 104/7

17              189
 9              196
 7              209
 7              217

Looks like you win for the first try on BIG external drives.

Seriously, Vista does do some serious indexing behind the scenes (it is even user configurable for Search) and it might well be that "feature" which is making the difference here.

Sorry to have been the bringer of bad news :-(

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Seriously, Vista does do some serious indexing behind the scenes (it is even user configurable for Search) and it might well be that "feature" which is making the difference here.

Sorry to have been the bringer of bad news :-(

No bad news, any testing result is just good news :)... so, that means DirGetSize seems to win on Vista any time. If you're just into speed, you can use something like this:

if @OSVersion <> "WIN_VISTA" Then
        $aResult = _DirGetSizeEx($Path)
    Else
        $aResult = DirGetSize($Path)
    EndIf

I adjusted the UDF in the first post, so that now the returned array structure is the same as for DirGetSize. Nevertheless I still favor my solution, it might be slower, depending on the OS and if the folder has been scanned before, but the main advantage I still see and why I coded the UDF is still valid. DirGetSize() pauses the script and can not be interrupted during runtime. You can do this easily with _DirGetSizeEx() by defining a Global Bool like $bRunning = true and switch it with WM_COMMAND.

Thanks for testing and Best Regards

Edited by KaFu

Share this post


Link to post
Share on other sites

@KaFu

Nice one :) works great when folder keep changing :lmao:

Cheers, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Nice, but it will fail on large subfolders structure (due to limitations of recursive function calls).

+ The files/folders count is wrong...

Edited by MrCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

Nice, but it will fail on large subfolders structure (due to limitations of recursive function calls).

+ The files/folders count is wrong...

6 months later :D

My test errored at 4710 recursive calls ( hell of a lot better than the previous 380+ I remember ).


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Here is a remake (a significant modificated my old version and this one):

#cs ----------------------------------------------------------------------------
    AutoIt Version: 3.3.0.0
    Author:         KaFu, MrCreatoR
    Script Name, Version and Date: _DirGetSizeEx v05 (09-Jun-24)
#ce ----------------------------------------------------------------------------

_Example(@AppDataDir)

Func _Example($sPath)
    $i_TimerInit = TimerInit()
    $a_DirGetSize = DirGetSize($sPath, 1)
    $i_dif_DirGetSize = Round(TimerDiff($i_TimerInit), 0)
    
    $i_TimerInit = TimerInit()
    $a_DirGetSizeEx = _DirGetSizeEx($sPath, 1) ; <= recommended
    $i_dif_DirGetSizeEx = Round(TimerDiff($i_TimerInit), 0)
    
    $s_Results = StringFormat('[DirGetSize()]\n\nTime (ms):\t%s\nBytes:\t\t%s\nFile Count:\t%s\nFolder Count:\t%s', _
            $i_dif_DirGetSize, $a_DirGetSize[0], $a_DirGetSize[1], $a_DirGetSize[2])
    
    $s_ResultsEx = _
        StringFormat('[DirGetSizeEx()]\n\nTime (ms):\t%s\nBytes:\t\t%s\nFile Count:\t%s\nFolder Count:\t%s', _
            $i_dif_DirGetSizeEx, $a_DirGetSizeEx[0], $a_DirGetSizeEx[1], $a_DirGetSizeEx[2])
    
    MsgBox(64, 'Comparison DirGetSize() vs _DirGetSizeEx', _
        StringFormat($s_Results & '\n\n===============================\n\n' & $s_ResultsEx))
EndFunc

; #FUNCTION# ====================================================================================================
; Name...........:  _DirGetSizeEx
; Description....:  Returns the size in bytes of a given directory.
; Syntax.........:  _DirGetSizeEx($sPath, $iFlag=0, $iRecurse_Level=-1)
; Parameters.....:  $sPath          - The directory path to get the size from, e.g. "C:\Windows".
;                   $iFlag          - [Optional] This flag determines the behaviour and result of the function,
;                                       and can be a combination of the following:
;                                               0 = (Default)
;                                               1 = Extended mode is On -> returns an array that contains extended information
;                                                   (see Remarks for native DirGetSize() function).
;                                               2 = Don't get the size of files in subdirectories (recursive mode is Off)
;                   $iRecurse_Level - [Optional] Determines the recursion level of subfolders to check (only if $iFlag < 2).
;                   
; Return values..:  Success         - Returns an array:
;                                                       $aRet_Array[0] = Bytes
;                                                       $aRet_Array[1] = File Count
;                                                       $aRet_Array[2] = Folder Count
;                   Failure         - Returns -1 and sets @error to 1 if the path doesn't exist.
;
; Author.........:  Initial Idea by KaFu, ReCoded by G.Sandler (a.k.a MrCreatoR).
; Modified.......:  
; Remarks........:  * Faster than DirGetSize() in the inital run on XP, slower in a repeated run,
;                       DirGetSize() seems to cache the result.
;                   * DirGetSize() can not be interrupted / stopped, that's the main reason for this UDF.
;                   * On Vista DirGetSize seems to be much faster than on XP, thus if you're only into speed use something like:
;                       ================== Code =========================
;                           If @OSVersion <> "WIN_VISTA" Then
;                               $aRet_Array = _DirGetSizeEx($sPath)
;                           Else
;                               $aRet_Array = DirGetSize($sPath)
;                           EndIf
;                       ================== Code =========================
;
;                   * Main advantage of _DirGetSizeEx() is that during runtime you can easily implement a progress count
;                      or interrupt the function with a global variable
;                      (just define a bool something like $iRunning = True and switch it with WM_COMMAND)
;
; Related........:  DirGetSize()?
; Link...........:  http://www.autoitscript.com/forum/index.php?showtopic=88094
; Example........:  Yes.
; ===============================================================================================================
Func _DirGetSizeEx($sPath, $iFlag=0, $iRecurse_Level=-1)
    If Not StringInStr(FileGetAttrib($sPath & "\"), "D") Then Return SetError(1, 0, -1)
    
    Local $aRet_Array[3], $hSearch, $sNextFile, $sFilePath, $i = 0
    Local $iMax_Ret_Paths = 10000
    Local $aPathes[$iMax_Ret_Paths+1] = [1, $sPath]
    
    While $i < $aPathes[0]
        $i += 1
        
        If $iFlag < 2 And $iRecurse_Level <> -1 And $i = $iRecurse_Level+1 Then ExitLoop
        
        $hSearch = FileFindFirstFile($aPathes[$i] & "\*")
        If $hSearch = -1 Then ContinueLoop
        
        While 1
            $sNextFile = FileFindNextFile($hSearch)
            If @error Then ExitLoop
            
            $sFilePath = $aPathes[$i] & "\" & $sNextFile
            
            If StringInStr(FileGetAttrib($sFilePath & "\"), "D") Then
                If $aPathes[0] >= $iMax_Ret_Paths Then
                    $iMax_Ret_Paths *= 2
                    ReDim $aPathes[$iMax_Ret_Paths+1]
                EndIf
                
                $aPathes[0] += 1
                $aPathes[$aPathes[0]] = $sFilePath
            Else
                $aRet_Array[1] += 1
                $aRet_Array[0] += FileGetSize($sFilePath)
            EndIf
        WEnd
        
        FileClose($hSearch)
        
        If $iFlag > 1 Then ExitLoop
    Wend
    
    If $iFlag > 0 And $iFlag <> 2 Then ;1 or 1 + 2 (3) - wich is mean that Extended mode is On.
        $aRet_Array[2] = $aPathes[0] - 1
        Return $aRet_Array
    EndIf
    
    Return $aRet_Array[0]
EndFunc ;==>_DirGetSizeEx

* No recursion limits + recursion level control + exactly the same options as in original DirGetSize function :D

Edited by MrCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

6 months later :D

My test errored at 4710 recursive calls ( hell of a lot better than the previous 380+ I remember ).

Yep, i must look at the date first (on all of it, not just the year), before posting :D

P.S

And BTW; signatures are really rules, i came here to this thread following by one of them (of KaFu's actualy ;) ).

Edited by MrCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

It does error out and do a false count? Hmmm, I can't reproduce that, this works fine for me:

#cs ----------------------------------------------------------------------------
    AutoIt Version: 3.3.0.0
    Author:         KaFu, MrCreatoR
    Script Name, Version and Date: _DirGetSizeEx v05 (09-Jun-24)
#ce ----------------------------------------------------------------------------

_Example(@AppDataDir)

Func _Example($sPath)
    $i_TimerInit = TimerInit()
    $a_DirGetSize = DirGetSize($sPath, 1)
    $i_dif_DirGetSize = Round(TimerDiff($i_TimerInit), 0)

    $i_TimerInit = TimerInit()
    $a_DirGetSizeEx = _DirGetSizeEx($sPath, 1) ; <= recommended
    $i_dif_DirGetSizeEx = Round(TimerDiff($i_TimerInit), 0)

    $i_TimerInit = TimerInit()
    $a_DirGetSizeExKaFu = _DirGetSizeExKaFu($sPath)
    $i_dif_DirGetSizeExKaFu = Round(TimerDiff($i_TimerInit), 0)

    $s_Results = StringFormat('[DirGetSize()]\n\nTime (ms):\t%s\nBytes:\t\t%s\nFile Count:\t%s\nFolder Count:\t%s', _
            $i_dif_DirGetSize, $a_DirGetSize[0], $a_DirGetSize[1], $a_DirGetSize[2])

    $s_ResultsEx = _
        StringFormat('[DirGetSizeEx()]\n\nTime (ms):\t%s\nBytes:\t\t%s\nFile Count:\t%s\nFolder Count:\t%s', _
            $i_dif_DirGetSizeEx, $a_DirGetSizeEx[0], $a_DirGetSizeEx[1], $a_DirGetSizeEx[2])

    $s_ResultsExKaFu = _
        StringFormat('[DirGetSizeExKaFu()]\n\nTime (ms):\t%s\nBytes:\t\t%s\nFile Count:\t%s\nFolder Count:\t%s', _
            $i_dif_DirGetSizeExKaFu, $a_DirGetSizeExKaFu[0], $a_DirGetSizeExKaFu[1], $a_DirGetSizeExKaFu[2])

    MsgBox(64, 'Comparison DirGetSize() vs _DirGetSizeEx', _
        StringFormat($s_Results & '\n\n===============================\n\n' & $s_ResultsEx & '\n\n===============================\n\n' & $s_ResultsExKaFu))
EndFunc

; #FUNCTION# ====================================================================================================

; Name...........:  _DirGetSizeEx
; Description....:  Returns the size in bytes of a given directory.
; Syntax.........:  _DirGetSizeEx($sPath, $iFlag=0, $iRecurse_Level=-1)
; Parameters.....:  $sPath          - The directory path to get the size from, e.g. "C:\Windows".
;                   $iFlag          - [Optional] This flag determines the behaviour and result of the function,
;                                       and can be a combination of the following:
;                                               0 = (Default)
;                                               1 = Extended mode is On -> returns an array that contains extended information
;                                                   (see Remarks for native DirGetSize() function).
;                                               2 = Don't get the size of files in subdirectories (recursive mode is Off)
;                   $iRecurse_Level - [Optional] Determines the recursion level of subfolders to check (only if $iFlag < 2).
;
; Return values..:  Success         - Returns an array:
;                                                       $aRet_Array[0] = Bytes
;                                                       $aRet_Array[1] = File Count
;                                                       $aRet_Array[2] = Folder Count
;                   Failure         - Returns -1 and sets @error to 1 if the path doesn't exist.
;
; Author.........:  Initial Idea by KaFu, ReCoded by G.Sandler (a.k.a MrCreatoR).
; Modified.......:
; Remarks........:  * Faster than DirGetSize() in the inital run on XP, slower in a repeated run,
;                       DirGetSize() seems to cache the result.
;                   * DirGetSize() can not be interrupted / stopped, that's the main reason for this UDF.
;                   * On Vista DirGetSize seems to be much faster than on XP, thus if you're only into speed use something like:
;                       ================== Code =========================
;                           If @OSVersion <> "WIN_VISTA" Then
;                               $aRet_Array = _DirGetSizeEx($sPath)
;                           Else
;                               $aRet_Array = DirGetSize($sPath)
;                           EndIf
;                       ================== Code =========================
;
;                   * Main advantage of _DirGetSizeEx() is that during runtime you can easily implement a progress count
;                      or interrupt the function with a global variable
;                      (just define a bool something like $iRunning = True and switch it with WM_COMMAND)
;
; Related........:  DirGetSize()?
; Link...........:  http://www.autoitscript.com/forum/index.php?showtopic=88094
; Example........:  Yes.
; ====================================================================================================
Func _DirGetSizeEx($sPath, $iFlag=0, $iRecurse_Level=-1)
    If Not StringInStr(FileGetAttrib($sPath & "\"), "D") Then Return SetError(1, 0, -1)

    Local $aRet_Array[3], $hSearch, $sNextFile, $sFilePath, $i = 0
    Local $iMax_Ret_Paths = 10000
    Local $aPathes[$iMax_Ret_Paths+1] = [1, $sPath]

    While $i < $aPathes[0]
        $i += 1

        If $iFlag < 2 And $iRecurse_Level <> -1 And $i = $iRecurse_Level+1 Then ExitLoop

        $hSearch = FileFindFirstFile($aPathes[$i] & "\*")
        If $hSearch = -1 Then ContinueLoop

        While 1
            $sNextFile = FileFindNextFile($hSearch)
            If @error Then ExitLoop

            $sFilePath = $aPathes[$i] & "\" & $sNextFile

            If StringInStr(FileGetAttrib($sFilePath & "\"), "D") Then
                If $aPathes[0] >= $iMax_Ret_Paths Then
                    $iMax_Ret_Paths *= 2
                    ReDim $aPathes[$iMax_Ret_Paths+1]
                EndIf

                $aPathes[0] += 1
                $aPathes[$aPathes[0]] = $sFilePath
            Else
                $aRet_Array[1] += 1
                $aRet_Array[0] += FileGetSize($sFilePath)
            EndIf
        WEnd

        FileClose($hSearch)

        If $iFlag > 1 Then ExitLoop
    Wend

    If $iFlag > 0 And $iFlag <> 2 Then ;1 or 1 + 2 (3) - wich is mean that Extended mode is On.
        $aRet_Array[2] = $aPathes[0] - 1
        Return $aRet_Array
    EndIf

    Return $aRet_Array[0]
EndFunc ;==>_DirGetSizeEx


Func _DirGetSizeExKaFu($sPath = @ScriptDir)
    Local $sSearch, $aResult[3], $aResult_sub[3]
    If StringRight($sPath, 1) <> "\" Then $sPath &= "\" ; Ensure $sPath has a trailing slash
    $sSearch = FileFindFirstFile($sPath & "*.*")
    While 1
        $sNext = FileFindNextFile($sSearch) ; check if next file can be found, otherwise exit loop
        If @error Then ExitLoop
        If StringInStr(FileGetAttrib($sPath & $sNext), "D") Then
            $aResult[2] += 1
            $aResult_sub = _DirGetSizeExKaFu($sPath & $sNext)
            $aResult[0] += $aResult_sub[0]
            $aResult[1] += $aResult_sub[1]
            $aResult[2] += $aResult_sub[2]
        Else
            $aResult[1] += 1
            $aResult[0] += FileGetSize($sPath & $sNext)
        EndIf
    WEnd
    FileClose($sSearch)
    Return $aResult
EndFunc   ;==>_DirGetSizeEx

In theory I could hit the max. recursion level, but for that someone would have to have a directory structure 4710 steps deep :D , or did I miss something?

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Hi, All!

Perso, for my scripts in AutoIt, I use often the DIR command, who is powerfull, fast, and easy.

Example(s):

#include <Constants.au3>

Const $clef="fichier(s)"
;Const $clef="file(s)"

MsgBox(0,"Dir Size",dirsize("C:\temp"))
MsgBox(0,"Dir Size",dirsize2("D:\Dev\Autoit"))
MsgBox(0,"Dir Size",dirsize3("C:\_trsfr"))
Exit


Func dirsize($dir)
    Local $f,$line
    $f=FileOpen("temp.bat",2)
    FileWriteLine($f,"@echo off")
    FileWriteLine($f,"setlocal")
    FileWriteLine($f,'CD /D"'& $dir &'"')
    FileWriteLine($f,"FOR /F ""tokens=*"" %%i IN ('dir /S /W /-C ^| find """&$clef&"""') DO SET SIZE=%%i")
    FileWriteLine($f,"echo %SIZE%")
    FileWriteLine($f,"endlocal")
    FileWriteLine($f,"exit")
    FileClose($f)

    Local $pip=Run(@ComSpec &" /c"& @ScriptDir &"\temp.bat",$dir, @SW_HIDE, $STDOUT_CHILD)
    $vret=""
    While 1
        $line = StdoutRead($pip)
        If @error Then ExitLoop
        If StringLen($line)>0 Then   ExitLoop
      ;MsgBox(0, StringLen($line), $line)
    Wend
    Return $line
EndFunc


Func dirsize2($dir)
    Local $f,$line,$vret
    $f=FileOpen("temp.bat",2)
    FileWriteLine($f,"@echo off")
    FileWriteLine($f,'CD /D"'& $dir &'"')
    FileWriteLine($f,"dir /S /W /-C")
    FileWriteLine($f,"exit")
    FileClose($f)

    Local $pip=Run(@ComSpec &" /c"& @ScriptDir &"\temp.bat",$dir, @SW_HIDE, $STDOUT_CHILD)
    $vret=""
    While 1
        $line = StdoutRead($pip)
        If @error Then ExitLoop
        If StringInStr($line,$clef)>0 Then   $vret=$line
    Wend
    Return $vret
EndFunc


Func dirsize3($dir)
    Local $line,$vret
    $cde='dir "'& $dir &'" /S /W /-C'
    Local $pip=Run(@ComSpec &" /c"& $cde,$dir, @SW_HIDE, $STDOUT_CHILD)
    $vret=""
    While 1
        $line = StdoutRead($pip)
        If @error Then ExitLoop
        If StringInStr($line,$clef)>0 Then   $vret=$line
    Wend
    Return $vret
EndFunc

WARNING: Do not forget to change the "clef" for your (computer) language (french, in these examples), ans set your directory(ies) choice.

Edited by Michel Claveau

Share this post


Link to post
Share on other sites

In theory I could hit the max. recursion level, but for that someone would have to have a directory structure 4710 steps deep

Yes, and we should reproduce it by creating this level:

$sInit_Dir = @TempDir & "\~Recursion_Test"

For $i = 1 To 4710 + 1
    $sInit_Dir &= "\" & $i
Next

DirCreate($sInit_Dir)

But it seems that my system (FAT32 file system?) does not allow such long recursion level of subfolders, so i personaly can't reproduce it. But it's can crash, so better way is to use loop, as i did :D .


 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

But it seems that my system (FAT32 file system?) does not allow such long recursion level of subfolders, so i personaly can't reproduce it. But it's can crash, so better way is to use loop, as i did :D .

Normally filelength is restricted to 260 characters, even on NTFS.

"The operating system API puts a limit (called MAX_PATH) of 260 characters for the complete name with the path included."

http://vlaurie.com/computers2/Articles/filenames.htm

http://www.ntfs.com/ntfs_vs_fat.htm

There are ways around it in NTFS (pre-prending \\?\ to the dir letter) and I think the theoratical max is 65536 letters, but imho a directory depth of > 10 or lets say > 20 is very ununsual. Personally i think theres NO directory structure in the world going down 4710 steps :D .

You mentioned that the files/folders count is wrong? Couldn't verfify that, what did you do test assume this?

Share this post


Link to post
Share on other sites

Hi!

NTFS max-length-filename are: 255 with "code-page" & 32767 with Unicode file's name.

@+

--

MCI

Share this post


Link to post
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
Sign in to follow this  
Followers 0