Folder Size Return 0

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
btpoole
Posts: 15
Joined: 04 Sep 2015 06:28

Folder Size Return 0

#1 Post by btpoole » 15 Dec 2015 09:23

Hello all
I am attempting to loop thru a main directory check the the subfolders for a file called log.txt. The log file contains the folder size. If the log file does not exist I want to write the directory's side to the log file and save it. The sub directories being checked are fairly small to start with, maybe 550 bytes, but when I check the size with script it returns 0. Here is part of the script. If I check the folder properties it displays approx 550. The next step would be to retrieve the value in the log file if it exist and compare it to the current size of the folder to see if it is changing.

Code: Select all

setLocal EnableDelayedExpansion 
   FOR /R c:\main %%G in (.) DO (
   Pushd %%G
    Echo now in %%G
      IF EXIST log.txt. (
             ECHO FILE HERE
       ) ELSE (
      ECHO FILE IS MISSING
      ECHO CREATE LOG FILE
      echo DIR %%G SIZE IS:   %%~zG
      echo %%G~zG>log.txt
          )

 Popd )
Echo "back home"
           
)


Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Folder Size Return 0

#2 Post by Squashman » 15 Dec 2015 09:38

Did you notice you are using the command modifier correctly in the first line but not the second line.

Code: Select all

echo DIR %%G SIZE IS:   %%~zG
echo %%G~zG>log.txt


Regardless of that, you would need to parse all the files in the directory and add up their size to get the total for the directory. The z modifier will not work with directories.

btpoole
Posts: 15
Joined: 04 Sep 2015 06:28

Re: Folder Size Return 0

#3 Post by btpoole » 15 Dec 2015 10:02

Ah, thank you for pointing that out. Didn't see it. So, windows has no command to use in batch file to get directory size?
Thanks again

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Folder Size Return 0

#4 Post by Squashman » 15 Dec 2015 10:51

Well you would only have to add two lines of code to do it.
One line to initialize a variable to ZERO.

Code: Select all

 set dirsize=0

And a FOR command to iterate over all the files in the directory.

Code: Select all

FOR %%G IN (*) DO set /a dirsize+=%%~zG

Compo
Posts: 600
Joined: 21 Mar 2014 08:50

Re: Folder Size Return 0

#5 Post by Compo » 15 Dec 2015 10:57

I would probably go for something like this:

Code: Select all

@Echo Off
SetLocal
(Set ID=%~1)
(Set SW=/L /S /NJH /BYTES /FP /NC /NDL /NFL /TS /XJ /R:0 /W:0)
If Not Defined ID (Set ID=%~dp0)
For /F "Tokens=1-2 Delims=: " %%a In ('RoboCopy %ID% NULL %SW%') Do (
   If %%a==Bytes Echo=Directory %ID% Size in %%a=%%b)
Ping -n 11 0.0.0.0 1>Nul
Just drag and drop my directory onto it or run the script with the directory path as the parameter.

btpoole
Posts: 15
Joined: 04 Sep 2015 06:28

Re: Folder Size Return 0

#6 Post by btpoole » 15 Dec 2015 18:55

Thank you both for valuable information.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Folder Size Return 0

#7 Post by thefeduke » 16 Dec 2015 00:21

This came out of generalizing your original framework and incorporating previous suggestions:
FolderSize.bat

Code: Select all

@Echo Off
:FolderSize [folder]
    setLocal EnableDelayedExpansion
    set "log=log.txt"
    set "target=c:\main"
    If .%~1 NEQ . Set "target=%~1"
    set "dirsize=0"
    set "dirtotal=0"
    FOR /R %target% %%G in (.) DO (
        Pushd %%G
        FOR %%D IN (*) DO set /a dirsize+=%%~zD
        echo DIR %%G SIZE IS:   !dirsize!
        If Exist %log% (
            Echo.Found '%%~dpG%log%'
        ) Else (
            >%log% Echo.!dirsize!
            Echo.Created '%%~dpG%log%'
        )
        set /a dirsize=!dirsize!/1024
        set /a dirtotal+=!dirsize!
        set "dirsize=0"
        Popd
    )
    Echo.Total subfolder space= '%dirtotal%' KB
    Exit /b

Some output:

Code: Select all

L:\Programs>foldersize dostips
DIR L:\Programs\dostips\. SIZE IS:   213145
Created 'L:\Programs\log.txt'
DIR L:\Programs\dostips\TestNums\. SIZE IS:   59444
Created 'L:\Programs\DOStips\log.txt'
Total subfolder space= '266' KB

L:\Programs>foldersize dostips
DIR L:\Programs\dostips\. SIZE IS:   213153
Found 'L:\Programs\log.txt'
DIR L:\Programs\dostips\TestNums\. SIZE IS:   59458
Found 'L:\Programs\DOStips\log.txt'
Total subfolder space= '266' KB

L:\Programs>type dostips\log.txt
213145

I hope that it suits.
John A.
Last edited by thefeduke on 16 Dec 2015 01:22, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Folder Size Return 0

#8 Post by foxidrive » 16 Dec 2015 01:22

Those counting directory size using CMD math need to be aware that it tops out at 2 GB.

Using the DIR command in a for /f loop is another way to get the directory size, and doesn't rely on maths.


Compo wrote:I would probably go for something like this:

I had some problems with robocopy in Windows 8.1 so tweaked your code. The %~dp0 can contain & characters also so it needs to be quoted.

Using robocopy is a good plan though.

Code: Select all

@echo Off
SetLocal
Set SW=/L /S /NJH /BYTES /FP /NC /NDL /NFL /TS /XJ /R:0 /W:0
If "%~1"=="" (Set "ID=%~dp0.") else (Set "ID=%~1")
For /F "Tokens=1,3" %%a In ('RoboCopy "%ID%" "%temp%" %SW%') Do (
   If "%%a"=="Bytes" Echo(The directory "%ID%" contains %%b bytes)
Ping -n 11 0.0.0.0 1>Nul

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Folder Size Return 0

#9 Post by thefeduke » 16 Dec 2015 16:07

foxidrive wrote:Those counting directory size using CMD math need to be aware that it tops out at 2 GB.

Using the DIR command in a for /f loop is another way to get the directory size, and doesn't rely on maths.

True enough and much neater, too. That overall total was out of scope anyway.
Replace:

Code: Select all

        FOR %%D IN (*) DO set /a dirsize+=%%~zD
        echo DIR %%G SIZE IS:   !dirsize!
with:

Code: Select all

        FOR /F "usebackq tokens=1-4,5* " %%i in (`DIR /-C`) do (
            IF "File(s)"=="%%j" (
                set "dirsize=%%k"
                Echo Folder %%G Size is: !dirsize! %%l from directory list
            )
        )
in my example above.
John A.

btpoole
Posts: 15
Joined: 04 Sep 2015 06:28

Re: Folder Size Return 0

#10 Post by btpoole » 17 Dec 2015 09:08

thefeduke wrote:This came out of generalizing your original framework and incorporating previous suggestions:
FolderSize.bat

Code: Select all

@Echo Off
:FolderSize [folder]
    setLocal EnableDelayedExpansion
    set "log=log.txt"
    set "target=c:\main"
    If .%~1 NEQ . Set "target=%~1"
    set "dirsize=0"
    set "dirtotal=0"
    FOR /R %target% %%G in (.) DO (
        Pushd %%G
        FOR %%D IN (*) DO set /a dirsize+=%%~zD
        echo DIR %%G SIZE IS:   !dirsize!
        If Exist %log% (
            Echo.Found '%%~dpG%log%'
        ) Else (
            >%log% Echo.!dirsize!
            Echo.Created '%%~dpG%log%'
        )
        set /a dirsize=!dirsize!/1024
        set /a dirtotal+=!dirsize!
        set "dirsize=0"
        Popd
    )
    Echo.Total subfolder space= '%dirtotal%' KB
    Exit /b

Some output:

Code: Select all

L:\Programs>foldersize dostips
DIR L:\Programs\dostips\. SIZE IS:   213145
Created 'L:\Programs\log.txt'
DIR L:\Programs\dostips\TestNums\. SIZE IS:   59444
Created 'L:\Programs\DOStips\log.txt'
Total subfolder space= '266' KB

L:\Programs>foldersize dostips
DIR L:\Programs\dostips\. SIZE IS:   213153
Found 'L:\Programs\log.txt'
DIR L:\Programs\dostips\TestNums\. SIZE IS:   59458
Found 'L:\Programs\DOStips\log.txt'
Total subfolder space= '266' KB

L:\Programs>type dostips\log.txt
213145

I hope that it suits.
John A.


Working with above I get almost exactly what I need. The one problem is that each log file after the first contains the previous subfolder sizes also. The first subfolder log.txt is correct, but each one after includes all the previous sizes. Thank you for your direction.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Folder Size Return 0

#11 Post by thefeduke » 17 Dec 2015 14:57

btpoole wrote:Working with above I get almost exactly what I need. The one problem is that each log file after the first contains the previous subfolder sizes also. The first subfolder log.txt is correct, but each one after includes all the previous sizes. Thank you for your direction.
I was anguishing about that while working on the accuracy of the size in the log file.
I cannot explain it. It shows correctly when I echo to the console but not when redirected to the file. I can only attribute this to the 'in (.)' of your original FOR statement. You might notice that your folder when displayed by %%G shows a '.' after it using this approach to define the loop.

Anyway, this should fix it up:

Code: Select all

@Echo Off
:FolderSize folder
    setLocal EnableDelayedExpansion
    set "log=log.txt"
    set "target=L:\programs"
    If .%~1 NEQ . Set "target=%~1"
    call set "dirsize=0"
    FOR /F "usebackq tokens=1-4,5* " %%E in (`DIR %target% /A:D /S /-C`) do (
        IF /I "Directory" EQU "%%E" (
            Pushd %%G
            FOR /F "usebackq tokens=1-4,5* " %%i in (`DIR /A:-S /-C`) do (
                IF "File(s)"=="%%j" (
                    Set "dirsize=%%k"
                    Echo.&Echo Folder '%%G' Size: !dirsize! %%l
                )
            )
            If Exist %log% (
                Echo.Found '%log%'
                type %log%
            ) Else (
                >%log% Echo.!dirsize!
                Echo.Created '%%~dpG%log%'
            )
            Set "dirsize=0"
            Popd
        )
    )
    Exit /b
Run it once to build missing log files. A second run lets you see the contents to check.

I do not know how accurate you need to have the log files. By definition, when the log file is created it is in error, being short by the length of the log file just created. I did write the code to correct the contents of the log file before writing it and can move it into the above example if you go with this approach and need dead accuracy.

John A.
Last edited by thefeduke on 18 Dec 2015 01:48, edited 1 time in total.

btpoole
Posts: 15
Joined: 04 Sep 2015 06:28

Re: Folder Size Return 0

#12 Post by btpoole » 17 Dec 2015 15:31

Yes, I did noticed the . in the log file. I don't have to have dead accuracy. The real purpose of the log file checking the folder size is to compare it to a future run of the file to see if a process is still running and creating content. As long as the current log file content is less than the future folder size when script is ran, I know the process is still running. I couldn't think of another way to check this. I will have multiple instances of the same process running creating content in individual folders. If one of the instances stops, I hope the script checking the folder sizes initiates another script that produces a warning window, or something of the like.
Thanks for taking time in helping.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Folder Size Return 0

#13 Post by thefeduke » 18 Dec 2015 01:56

I corrected one line in previous post to add '%target%':

Code: Select all

    FOR /F "usebackq tokens=1-4,5* " %%E in (`DIR %target% /A:D /S /-C`) do (
As it was it worked on current directory and its sub-directories.
John A.

btpoole
Posts: 15
Joined: 04 Sep 2015 06:28

Re: Folder Size Return 0

#14 Post by btpoole » 23 Dec 2015 22:24

Once again thanks for your help but I have run into a situation. The script you provided works great for what I was trying to accomplish but something has changed. The folder structure has been changed on me.

Original structure:

C:\main\sub1

New structure:

C:\main\sub1\sub2

Yes, your script does what it was designed to do, it cycles thru the main, sub1 and sub2 getting the folder sizes. My problem is this. After my original bat file runs, the sub1 folders are created along with a log.txt file in side sub1 that stores the size of the sub1. I was then using your script in a second bat file I'll call monitor.bat which loops thru sub1 check for log.txt existence and it's content. If the value in log.txt is less than the current value of sub1, the bat will start a php script which is stored in sub1. If the value is = or > than the value of sub1 it skips and continues. Since I know have a sub2 to deal with I encounter the problem that it tries to read a log.txt in sub2 which may or may not have any content. And if the log.txt in sub2 is less than the value of sub2 it tries to start the php script in sub2 which doesn't exist. I guess what I am asking is there a way to calc the values as it is doing but only for sub1 (which would include the size of sub2) but without entering into sub2 and adding it's size up? Or a way to prevent it from trying to execute the php in sub2?

Just for refresher here is the code

Code: Select all

FOR /R %target% %%G in (.) DO (
Pushd %%G
   FOR %%D IN (*) DO set /a dirsize+=%%~zD
        echo DIR %%G SIZE IS:   !dirsize!

              If Exist %log% (                              
             Echo.Found '%%~dpG%log%'
                        SET /p logsize=<log.txt
                        Echo CURRENT LOG SIZE . . . . . . . !logsize!
                        set "dirsize=0"
                  FOR %%D IN (*) DO set /a dirsize+=%%~zD     LIMIT HERE TO sub1   
                     Echo.NEW DIR %%G SIZE IS:   !dirsize!
                        If !logsize! LSS !dirsize! (     
                        Echo ********RESETTING %%G************************
                         start "Y:\Program Files (x86)\PHP5\php.exe"  test.php
                        
                        ) Else (
                        >%log% Echo.!dirsize!            
                         Echo NEW LOG SAVED. . . . .
                  
                     )
                                       

        ) Else (

            >%log% Echo.!dirsize!

            Echo.Created '%%~dpG%log%'



        )

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Folder Size Return 0

#15 Post by thefeduke » 24 Dec 2015 00:26

btpoole wrote: is there a way to calc the values as it is doing but only for sub1 (which would include the size of sub2) but without entering into sub2 and adding it's size up? Or a way to prevent it from trying to execute the php in sub2?
As it stands now I believe that each directory could have a log file the is associated with the size of that particular directory regardless of the sizes above or below in the tree. Sub1 does not include the size of sub2 and the log file in the main target does not change while sub1 might be growing.
To develop a rule for this requirement is it safe to say that you wish to restrict log file activity to the target folder and no more that one level of sub-directory? This would imply that if you did want to act on sub2 in this structure your target would have to be C:\main\sub1\sub2 or C:\main\sub1 and that at target of C:\main would ignore sub2.
Please confirm or restate your requirement.
John A.

Post Reply