0

Appreciate anyone's help. I am quite stuck on this.

I am writing a bat script to move files from one folder to anther folder. (this part is simple enough)

However, before actually moving the file, I'd like to check whether the size of the file changes or not every 45 seconds. If the last size of the file is equal to the current size, then finally will move it. (Reason for this check is because the file in the source folder might still be in progress writing and we don't want to move it until it is finished)

Please help, I am open to suggestions

Currently have this code and am stuck:

for %%a in (%_fromFolder%\*%_fileName%*%_extension%) DO (
echo %%~za
set "fname=%~1"
set fSize = %%~za
timeout /t 45 /nobreak
:loop
if fSize == %%~za (
    echo %fSize%
    echo %%~za
    goto :moveF
) else (
    set fSize =%%~za
    timeout /t 45 /nobreak
    goto :loop
)

)

:moveF
move %~1 %_toFolder%
Squashman
  • 13,649
  • 5
  • 27
  • 36
  • Do the check outside the `FOR` command block. Just use the `FOR` command to get the file size and set it to a variable. Then do your check and timeout. – Squashman Aug 09 '18 at 21:39
  • If the file is open for writing, you will not be able to move it. Might you try moving it and check if move fails? – Alan Baljeu Aug 09 '18 at 21:42
  • Are you passing the file as an argument to this batch file? The only reason I ask is because of this line of code: `set "fname=%~1"`. There is no need for the `FOR` command to get the size if you already have the file name as an argument. – Squashman Aug 09 '18 at 21:44
  • @Squashman: thanks for your reply, but the folder may have more than 1 file to check and move. – Ed xTribal Aug 09 '18 at 21:44
  • @EdxTribal, you **CANNOT** do a `GOTO` inside a `FOR` command block. It breaks the `FOR` command. – Squashman Aug 09 '18 at 21:45
  • no, it is not taking file as an argument, from the first line "for %%a in ..." I am getting each files from the folder. but what I dont know how to do is check for each of those files whether the size changes or not every 45 seconds. – Ed xTribal Aug 09 '18 at 21:48
  • If you are getting each file from the `FOR` command why are you using the command line argument `%~1` twice in your code? – Squashman Aug 09 '18 at 22:01
  • @Squashman, I apologize the %~1 should not have been there and it should just been getting the files from the FOR – Ed xTribal Aug 09 '18 at 22:17

1 Answers1

1

I have placed comments in the code to explain what it is doing.

REM Get list of files
for %%G in ("%_fromFolder%\*%_fileName%*%_extension%") DO (
    REM Call function to check for the size of the file
    CALL :CHECK "%%G"
    REM Back from the Function. now move the file
    move "%%~G" "%_toFolder%"
)

GOTO :EOF

:CHECK
REM set the size of the file to a variable
set "fsize=%~z1"
REM delay program
timeout /t 45 /nobreak
REM check to see if the file size is the same. IF it is then leave the function
if "%fSize%"=="%~z1" GOTO :EOF
REM Go back to the check if the file size is not the same
GOTO CHECK
Squashman
  • 13,649
  • 5
  • 27
  • 36
  • Thank you so much for that, If you dont mind me asking why do we use %~z1 in CHECK instead of %~zG ? Does the z1 represent the size of the current file %%G ? Sorry, Im still kind of new to the bat scripts. – Ed xTribal Aug 09 '18 at 22:13
  • 1
    When you CALL a label, any passed arguments become arguments to the label. Just like with a regular batch file. – Squashman Aug 09 '18 at 22:15
  • @EdxTribal The scope of a for meta variable is limited to the line or (code block) of the for command. So you could reuse the same variable in the sub routine - albeit this would obfuscate the code ;-) –  Aug 09 '18 at 22:35