Search code examples
batch-filecomparisoncomparison-operators

Error with batch file comparison operators


Can't work this out, I'm not hugely familiar with batch scripts although use them where I can.

I have a script that tests if the current file is larger then 4GB and to do on action if it is, and another action if not.

I have the following in a .bat file:

 %~d1

set fsize=%~z1

if %fsize% gtr 4000000000 (
    echo "exit"
) ELSE (
    echo "keep going"
)

pause

When I drag a 4.8 GB file onto this file, I get this result in command line:

set fsize=4876064456
if 4876064456 GTR 4000000000 (echo "exit" )  ELSE (echo "keep going" )
"keep going"

When I drag a 60 MB file onto it, I get this:

set fsize=61840920

if 61840920 GTR 4000000000 (echo "exit" )  ELSE (echo "keep going" )
"keep going"

If I change the operator to LSS, I get the "exit" result from both files instead. Why isn't it doing a proper comparison?


Solution

  • The Windows command processor cmd.exe uses the C function strtol to convert a string to an integer for doing an integer comparison. The type long int is a 32-bit signed integer (not always, depends on C compiler, but for compilation of cmd.exe). For that reason the value range is limited to −2^31 to 2^31−1 which is −2147483648 to 2147483647.

    This limitation can be worked around for checking if a file is ≥4294967296 as demonstrated by this code:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    if "%~1" == "" echo ERROR: %~nx0 must be run with a file name.& goto EndBatch
    if not exist "%~1" echo ERROR: File "%~1" not found.& goto EndBatch
    if exist "%~1\" echo ERROR: "%~1" is not a file.& goto EndBatch
    
    set "fsize=%~z1"
    if "%fsize:~9,1%" == "" echo File is smaller than 4 GB.& goto EndBatch
    if not "%fsize:~10,1%" == "" echo File is larger than 4 GB.& goto EndBatch
    if "%fsize%" LSS "4294967296" echo File is smaller than 4 GB.& goto EndBatch
    echo File is equal or larger than 4 GB.
    :EndBatch
    pause
    endlocal
    

    The first condition is true if the file size string has less than 10 characters which means the file size is less than 1000000000 bytes.

    The second condition is true if the file size string has more than 10 characters which means the file size is greater than 9999999999 bytes.

    The third condition is true if the file size string enclosed in double quotes with exactly 10 characters is less than the string "4294967296" which means the file size is less than 4294967296 bytes.

    See the following answers for more information about string and integer comparisons: