Process a file after a file is finished being written Windows Command Line .bat

julesverne picture julesverne · Jun 21, 2013 · Viewed 9k times · Source

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.

Answer

dbenham picture dbenham · Jun 21, 2013

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.