Search code examples
windowsbatch-filecmdfilesize

Getting a filesize in a batch file where the filename is known


I'm trying to write a simple batch file that allows me to compare two filesizes, where both filenames are already known and set within the batch file itself.

But just getting one filesize is proving difficult. Here is the smallest piece of code that replicates the problem:

IF EXIST "flava.jpg" (

  REM Get current filesize 
  FOR /F %%A in ("flava.jpg") DO SET _existingFileSize=%%~zA

  ECHO %_existingFileSize%

) ELSE (

  ECHO File not found.

)

From what I've read here, it should echo the variable's contents. What's going on?


Solution

  • setlocal enabledelayedexpansion
    IF EXIST "flava.jpg" (
      REM Get current filesize 
      FOR /F %%A in ("flava.jpg") DO SET _existingFileSize=%%~zA
      ECHO !_existingFileSize!
    ) ELSE (
      ECHO File not found.
    )
    

    or

    IF EXIST "flava.jpg" (
      REM Get current filesize 
      FOR /F %%A in ("flava.jpg") DO SET _existingFileSize=%%~zA
      CALL ECHO %%_existingFileSize%%
    ) ELSE (
      ECHO File not found.
    )
    

    or

    set "_existingfilesize="
    FOR /F %%A in ("flava.jpg") DO SET _existingFileSize=%%~zA
    if defined _existingfilesize (echo %_existingfilesize%) else (echo file not found)
    

    The issue is that within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).

    Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.

    Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.

    Note therefore the use of CALL ECHO %%var%% which displays the changed value of var. CALL ECHO %%errorlevel%% displays, but sadly then RESETS errorlevel.