Question

I've seen this question asked (not so much answered) for java and linux but not for Windows Command Line batch operation. I'll describe what I'd like to do using Windows Command Line. I'm pulling my hair out trying to figure this out.

A multimedia file is converting into folder X. Once the file conversion is completed it is then ftp'd using winSCP. the winSCP command line syntax I can probably figure out. It's the waiting for the file to finish converting that is troubling me.

One method I've outlined would be using a for loop like this:

file size is written to a variable

pause for 5 seconds using ftp nul ping trick (as described here in answer 1: Batch file to download a file from FTP)

then check to see if file size is same as previous variable if it is.. stop loop check and start winSCP. (I'm using winSCP instead of windows command line ftp as windows ftp doesn't run passively).

Problem is I haven't found a way to write a file size to a variable. Plus, I'd have to ensure that once the file has started to ftp that it stops looking at that file and waits to watch for a new multimedia file to enter the folder.

The real reason I'd like to do this is at the moment I'm waiting till all files are finished converting then uploading via ftp, which adds more time to the process, I really want this process to be automated via bat, but in addition it will save me time.

Thanks in advance for any help.

EDIT: I've just found this link to get the file size of a file: Windows command for file size only? It doesn't answer my question but is definitely a key part to the equation.

Was it helpful?

Solution

Getting the file size into a variable is simple - for %%F in (filePath) do set "size=%%~zF".

But I believe I can give you a much better solution.

Unlike Unix, most Windows processes get an exclusive lock on a file when they are writing to it. Assuming your conversion process continuously locks the output file during processing, then you can simply use the following to test if the file is locked (still being processed) or not locked (finished processing):

( (call ) >>outputFile.ext ) 2>nul && (
  echo The file is unlocked and ready for transfer
) || (
  echo The file is still being created
)

The (call ) syntax is simply a very fast command that does nothing - effectively a null op. This command is guaranteed not to have any output, so when you append the results of the command to your file, it is guaranteed not to change anything.

If the file is already locked because it is still being processed by your conversion program, then the redirection will fail. The 2>nul simply hides any error message due to redirection failure, and the && and || operators conditionally execute command(s) based on success or failure of prior command.

Update

The space in (call ) is critical, allowing the "null op" to not return an error (errorcode=0). Take away the space, (call), and the command returns an error (errorcode=1) which will break the lock detection algorithm. It is interesting that the form without a space returns an error without generating an error message. I believe those two commands are the most efficient way to clear or set the batch errorcode.

OTHER TIPS

Thanks to @dbenham I was able to come up with a rudimentary script, it is admittedly pretty ugly code but it works right now for what I need. As time progresses I intend on a more user friendly script with error catching. At the moment in order to run the script you have to edit the .bat with the folder being used rather than it being a user initiated variable. I also haven't asked the question what the userlogin and pw is for WinSCP but rather unsecurely at the moment have it built into the script. Obviously that will also eventually be a user asked question.

@echo off

SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION

:checkformovfile
REM Check if a .mov file has been added to the folder

for %%I in (*.*) do (if exist "H:\converted\*.mov" GOTO:checkfilecreation)

Goto :checkformovfile

:checkfilecreation
REM Now that a .mov file has been added to the folder check to see if the file has
REM completed the conversion or copying to the folder before starting ftp

CLS

for %%I in (*.mov) do ( (call ) >>%%I ) 2>nul && (cls && set b=%%I && @echo !b! 
is completed and transfer is ready && GOTO :fileready
) || (cls && echo %%I is still being created
)

:ContinueCheck
REM Go back to checkfilecreation module
GOTO :checkfilecreation


:fileready
REM copy completed file to uploaded folder
move /Y "H:\converted\!b!" "H:\uploaded\!b!"
echo
REM start ftp and upload file to home user folder on ftp site and write log
C:\WinSCP\WinSCP.exe /console /command "option batch on" "option confirm off" 

"open ftp://someuserlogin:someuserpw@someftpsite.com:21" "put H:\uploaded\!b! /home/user/!b!" "exit"||echo !b! uploaded successfully>log.txt

GOTO:checkformovfile

:eof

One solution is to try accessing the file while it's being used by another process (explorer.exe for example for copying).

Here is a sample code to overpass that :

@echo OFF
rem Let say the file you are copying is named BIGFILE.txt
:Loop
set /p test=<BIGFILE.txt >nul || ( Timeout 5 & goto Loop )
echo File ended copying
pause
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top