Skip to main content

How to Get Size of a File in Bytes in Batch Script

A common task in automation and file management scripts is to determine the size of a file. You might need to verify a download, check log file growth, ensure a file is not empty before processing it, or simply report on disk usage. While there are several ways to do this in Windows Batch, the most direct, efficient, and native method is by using a special modifier within a FOR loop.

This guide will provide a thorough explanation of the %%~z FOR variable modifier, demonstrate its use, show how to build it into a robust and reusable subroutine for your own scripts, and explain how it gracefully handles common issues like file paths with spaces or files that don't exist.

Why Get a File's Size in a Batch Script?

Determining a file's size programmatically is crucial for many scripting tasks:

  • Verification: Confirming that a file copy or download has completed and is not zero bytes.
  • Logging: Recording the size of log files or data archives as part of a process.
  • Conditional Logic: Only processing files that are within a certain size range.
  • Reporting: Creating simple inventory or status reports that include file sizes.

The Core Technique: The %%~z FOR Variable Modifier

The FOR command in Batch has a set of powerful modifiers (also called "parameter expansions") that can extract specific pieces of information about a file. The one we need for size is ~z.

When a FOR loop variable (e.g., %%A) represents a file, %%~zA expands to the size of that file in bytes.

Basic Usage and Syntax

@ECHO OFF
SET "filename=C:\Windows\System32\notepad.exe"

REM The FOR loop iterates over the single item in the set, which is our filename.
REM %%F will hold the full filename.
REM %%~zF will expand to its size in bytes.
FOR %%F IN ("%filename%") DO ECHO Size of "%%F" is %%~zF bytes.

Output:

Size of "C:\Windows\System32\notepad.exe" is 213504 bytes.
note

Your actual size for notepad.exe may vary depending on your Windows version.

Handling File Paths with Spaces

It is critical to enclose the filename/path in double quotes within the FOR loop's set: FOR %%F IN ("%filename%"). This ensures that file paths containing spaces are treated as a single item and parsed correctly.

Without the quotes, a path like "C:\Program Files\App\file.txt" would be seen as three separate items by the FOR loop.

A Practical, Reusable Subroutine (:GetFileSize)

For real-world scripting, it's best to encapsulate this logic in a callable subroutine. The following script provides a :GetFileSize subroutine that takes a filename as input and "returns" the size in a variable specified by the caller.

The Script with a Reusable Subroutine

@ECHO OFF
SETLOCAL

SET "myFile=C:\Windows\explorer.exe"

REM --- Example 1: Call the subroutine and get the size back ---
CALL :GetFileSize "%myFile%" fileSizeInBytes
IF DEFINED fileSizeInBytes (
ECHO The file size of "%myFile%" is %fileSizeInBytes% bytes.
) ELSE (
ECHO Could not find the file: "%myFile%"
)
ECHO(

REM --- Example 2: Handling a file that does not exist ---
CALL :GetFileSize "C:\path\to\a\non_existent_file.txt" fileSizeInBytes
IF DEFINED fileSizeInBytes (
ECHO This line should not be printed.
) ELSE (
ECHO The subroutine correctly reported the file does not exist.
)
ECHO(

GOTO :EOF

REM ======================================================================
:GetFileSize FilePath [ReturnVar]
:: Gets the size of a specified file in bytes.
:: %~1 [in] - The full path to the file to check.
:: %~2 [out] - Optional. The name of the variable to store the file size in.
:: The return variable will be undefined if the file does not exist.
:: If ReturnVar is not specified, the size is ECHOed to the console.
SETLOCAL
SET "filePath=%~1"
SET "fileSize="

REM Check if the file exists to run the FOR loop only when necessary.
IF EXIST "%filePath%" (
FOR %%F IN ("%filePath%") DO SET "fileSize=%%~zF"
)

(
ENDLOCAL
IF "%~2" NEQ "" (SET %~2=%fileSize%) ELSE (ECHO %fileSize%)
)
EXIT /B

Breakdown of the :GetFileSize Subroutine

  • SETLOCAL / ENDLOCAL: These commands create a localized scope for variables inside the subroutine, preventing unintended side effects on the main script's environment.
  • SET "filePath=%~1": Safely captures the first argument (the file path). %~1 removes any surrounding quotes from the argument.
  • IF EXIST "%filePath%": This is a crucial robustness check. It ensures the FOR loop only attempts to run on a file that actually exists, preventing wasted processing.
  • FOR %%F IN ("%filePath%") DO SET "fileSize=%%~zF": This is the core logic. It runs the loop (which will only iterate once for a single file) and sets the local fileSize variable to the result of %%~zF.
  • (ENDLOCAL & SET %~2=%fileSize%): This is a standard batch technique to "return" a value from a subroutine. It ends the SETLOCAL session and then, on the same logical line, sets the variable named by the second argument (%~2) in the parent script's context. If no second argument is given, it simply ECHOs the size.

How to Use the Subroutine

REM Store the size of mylog.txt in the variable 'logSize'
CALL :GetFileSize "C:\logs\mylog.txt" logSize

REM Check if the file existed and its size was retrieved
IF NOT DEFINED logSize (
ECHO C:\logs\mylog.txt not found.
) ELSE (
ECHO The log file is %logSize% bytes.
IF %logSize% GTR 1048576 ECHO Warning: Log file is larger than 1MB.
)

Handling "File Not Found" Scenarios

A great feature of using the FOR command for this purpose is its graceful handling of missing files. If you provide a path to a file that does not exist, the FOR loop simply does not iterate. It does not produce an error.

@ECHO OFF
REM This will not produce an error or any output.
FOR %%A IN ("C:\path\to\a\non_existent_file.txt") DO ECHO Size is %%~zA
ECHO Script continues without interruption.

This is why checking IF DEFINED on the return variable from our :GetFileSize subroutine is a reliable way to know if the file was found and its size was successfully retrieved.

Why This Method is Superior to DIR Parsing

Another common method to get file size is to parse the output of the DIR command.

REM --- Old, less reliable method ---
FOR /F "tokens=3,4" %%A IN ('dir "myfile.txt" ^| find "myfile.txt"') DO ECHO Size is %%A bytes

This method is fragile because:

  • The position of the file size (token=3) can change based on date/time format settings.
  • It requires complex parsing and is much slower.
  • The dir command format can vary between different Windows versions or language settings.

The %%~z modifier is direct, fast, and locale-independent, making it the superior choice.

Conclusion

Using the FOR command with the %%~z modifier is the most efficient, reliable, and native way to get a file's size in bytes within a Windows Batch script. It is faster and more robust than parsing the output of DIR.

By encapsulating this simple yet powerful command in a reusable subroutine like :GetFileSize, you can create a clean and powerful tool for all your file management and automation scripts.