I want to get the size of directory say C:\\Temp
in MB
using batch file. I don\'t need sizes of child directories or files, but the size of directo
@echo off
::robocopy "%~1" %TEMP% /S /L /BYTES /XJ /NFL /NDL /NJH
for /f "tokens=2 delims=: " %%a in ('
robocopy "%~1" %TEMP% /S /L /BYTES /XJ /NFL /NDL /NJH ^| find "Bytes"
') do set "bytes=%%a"
::1048576
set "beginJS=mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write("
set "endJS=));""
for /f %%N in (
'%beginJS% %bytes%/1048576 %endJS%'
) do set mb=%%N
echo mb=%mb%
It takes one argument - the folder which size you want to calculate
Here is a pure batch file solution (refer to the remarks in the code for some brief explanations):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define constants here:
set /A DIVISOR=1024 & rem (1024 Bytes = 1 KBytes, 1024 KBytes = 1 MByte,...)
set "ROUNDUP=#" & rem (set to non-empty value to round up results)
rem Get size of directory given as command line argument:
for /F "tokens=2 delims=: " %%B in ('
robocopy "%~1" "%~1" "*.*" /L /S /XJ /BYTES /NP /NFL /NDL /NJH ^| ^
find /I "Bytes"
') do set "BYTES=%%B"
if not defined BYTES set "BYTES=0"
rem Display result in Bytes and divide it to get KBytes, MBytes, etc.:
call :DIVIDE %BYTES% 1 RESULT
echo( Bytes: %RESULT%
call :DIVIDE %RESULT% %DIVISOR% RESULT REST
if defined ROUNDUP if 0%REST% GTR 0 set /A RESULT+=1
echo(KBytes: %RESULT%
call :DIVIDE %RESULT% %DIVISOR% RESULT REST
if defined ROUNDUP if 0%REST% GTR 0 set /A RESULT+=1
echo(MBytes: %RESULT%
call :DIVIDE %RESULT% %DIVISOR% RESULT REST
if defined ROUNDUP if 0%REST% GTR 0 set /A RESULT+=1
echo(GBytes: %RESULT%
endlocal
exit /B
:DIVIDE val_dividend val_divisor [ref_result] [ref_remainder]
rem Divide a huge number exceeding the 32-bit limitation
rem by a 32-bit number in the range from 1 to 1000000000;
rem the result might also exceed the 32-bit limitation.
setlocal EnableDelayedExpansion
set "DIVIDEND=%~1"
set "DIVISOR=%~2"
set "QUOTIENT=%~3"
set "REMAINDER=%~4"
rem Check whether dividend and divisor are given:
if not defined DIVIDEND (
>&2 echo(Too few arguments, dividend missing^^!
exit /B 2
) else if not defined DIVISOR (
>&2 echo(Too few arguments, divisor missing^^!
exit /B 2
)
rem Check whether dividend is purely numeric:
for /F "tokens=* delims=0123456789" %%N in ("!DIVIDEND!") do (
if not "%%N"=="" (
>&2 echo(Dividend must be numeric^^!
exit /B 2
)
)
rem Convert divisor to numeric value without leading zeros:
for /F "tokens=* delims=0" %%N in ("%DIVISOR%") do set "DIVISOR=%%N"
set /A DIVISOR+=0
rem Check divisor against its range:
if %DIVISOR% LEQ 0 (
>&2 echo(Divisor value must be positive^^!
exit /B 1
) else if %DIVISOR% GTR 1000000000 (
>&2 echo(Divisor value exceeds its limit^^!
exit /B 1
)
set "COLL=" & set "NEXT=" & set /A INDEX=0
rem Do a division digit by digit as one would do it on paper:
:LOOP
if "!DIVIDEND:~%INDEX%,1!"=="" goto :CONT
set "NEXT=!NEXT!!DIVIDEND:~%INDEX%,1!"
rem Remove trailing zeros as such denote octal numbers:
for /F "tokens=* delims=0" %%N in ("!NEXT!") do set "NEXT=%%N"
set /A NEXT+=0
set /A PART=NEXT/DIVISOR
set "COLL=!COLL!!PART!"
set /A NEXT-=PART*DIVISOR
set /A INDEX+=1
goto :LOOP
:CONT
rem Remove trailing zeros as such denote octal numbers:
for /F "tokens=* delims=0" %%N in ("%COLL%") do set "COLL=%%N"
if not defined COLL set "COLL=0"
rem Set return variables or display result if none are given:
if defined QUOTIENT (
if defined REMAINDER (
endlocal
set "%REMAINDER%=%NEXT%"
) else (
endlocal
)
set "%QUOTIENT%=%COLL%"
) else (
endlocal
echo(%COLL%
)
exit /B
Basically, the size of the contents of the directory given as command line argument is gathered by robocopy
, similar to npocmaka's approach; the resulting size in Bytes is stored in variable BYTES
.
Afterwards, several subroutine calls are done, each to divide the result by 1024
in order to get the size in KBytes, then MBytes and GBytes.
The values resulting from the divisions are incremented by 1
if there is a remainder in order to round up the sizes (similar to Windows Explorer, which for example displays 1 KB
for very small files). You can disable this feature by setting variable ROUNDUP
to an empty string, which leads to rounding down.
Since the set /A
command (and its division operator /
) can handle (signed) 32-bit integers only, the subroutine :DIVIDE
performs the actual division like one would do it on paper. The dividend (that is the number to be divided) is treated as a string, so the 32-bit range can be exceeded; the divisor (that is the number to divide by) however must not exceed it; rather it must be in the range from 1
to 1000000000
. The loop at :LOOP
consisting of goto :LOOP
and a conditional goto :CONT
constitutes a while-loop-like structure that iterates through all the decimal figures of the dividend and terminates after the last one has been reached.
The subroutine expects at least two arguments -- the values of the dividend and the divisor. It accepts even two more -- the name of a variable to hold the quotient (that is the division result) and another one to hold the remainder. If no optional arguments are given, the quotient is displayed on the console.
if you need exact values, go for another option. But if you need a rough value only (cut, not rounded, not 1024 as divisor but 1000 only):
@echo off
for /f "tokens=2 delims=," %%a in ('dir *^|findstr /e "Bytes"') do (
for /f "delims= " %%i in ("%%a") do set size=%%i
)
echo size in Bytes: %size%
echo that's about %size:~0,-4% KB
echo or about %size:~0,-8% MB
echo or about %size:~0,-12% GB
Advantage: this is string manipulation only, no math included, so it even works outside 32bit Integer (which would be limited to sizes up to about 2GB).
You can do it with a hybrid script [Batch/Vbscript] like this one :
@echo off
set Folder="C:\temp"
echo The size of %Folder% is
Call :GetSize %Folder%
pause
:GetSize
(
echo wscript.echo GetSize("%~1"^)
echo Function GetSize(MyFolder^)
echo Set fso = CreateObject("Scripting.FileSystemObject"^)
echo Set objFolder= fso.GetFolder(MyFolder^)
echo GetSize = FormatSize(objFolder.Size^)
echo End Function
echo '*******************************************************************
echo 'Function to format a number into typical size scales
echo Function FormatSize(iSize^)
echo aLabel = Array("bytes", "KB", "MB", "GB", "TB"^)
echo For i = 0 to 4
echo If iSize ^> 1024 Then
echo iSize = iSize / 1024
echo Else
echo Exit For
echo End If
echo Next
echo FormatSize = Round(iSize,2^) ^& " " ^& aLabel(i^)
echo End Function
echo '*******************************************************************
)>%tmp%\Size.vbs
Cscript /NoLogo %tmp%\Size.vbs
Del %tmp%\Size.vbs
Exit /b
Edit : on 30/03/2016 @12:11
And this a nice trick
the Liviu's hack for embedding vbscode in batch without temp files
I just discovered from npocmaka thanks to him
@echo off
Set Folder="c:\temp"
@cScript.EXE //noLogo "%~f0?.WSF" %Folder% //job:info %~nx0%*
pause
@exit /b 0
<job id="info">
<script language="VBScript">
wscript.echo GetSize(WScript.Arguments(0))
Function GetSize(MyFolder)
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFolder= fso.GetFolder(MyFolder)
GetSize = FormatSize(objFolder.Size)
End Function
'*******************************************************************
'Function to format a number into typical size scales
Function FormatSize(iSize)
aLabel = Array("bytes", "KB", "MB", "GB", "TB")
For i = 0 to 4
If iSize > 1024 Then
iSize = iSize / 1024
Else
Exit For
End If
Next
FormatSize = Round(iSize,2) & " " & aLabel(i)
End Function
'*******************************************************************
</script>
</job>