为什么我的批处理文件无法获得文件大小?

时间:2017-09-18 14:58:31

标签: windows batch-file cmd

我正在尝试编写一个Windows批处理文件,使用 ffmpeg 将整个文件夹与旧的.flv视频转换为* .mp4视频。

批处理文件或多或少有效,但我想在删除源文件之前做一些测试。其中一个测试是输出文件至少应该是原始文件的2/3,但我无法使其工作。

这是我的bat文件(包含所有调试回显线):

@echo off

setlocal EnableExtensions EnableDelayedExpansion

::-------------------------------------------------------------------------------------
:: get options and folder path
set opzione=%~1%
set cartella=%~2%
:: who's who?
if "%opzione:~3,1%"=="" (
    echo.
) else (
    if "%opzione:~0,1%"=="/" (
        echo.
    ) else (
        set opzione=%~2%
        set cartella=%~1%
    )
)
::echo.
::echo Cartella = %cartella%
::echo Opzione = %opzione%
::echo.



::-------------------------------------------------------------------------------------
:Check_path
    set FLV_FOLDER="%cartella%"

    if %FLV_FOLDER% == "" ( 
        echo ... Invalid
        goto :uscita
    ) else (
        echo ... OK.
    )

::-------------------------------------------------------------------------------------
:Check_Options (STILL W.I.P.)
    set Lista=0
    set Convert=0
    set Delete=0

    if "%opzione%"=="/c" (set Convert=1)
    if "%opzione%"=="/l" (set Lista=1)
    if "%opzione%"=="/d" (set Delete=1)

::echo Lista = %Lista%



::-------------------------------------------------------------------------------------
:Loop_path
@cls
echo Looping all .flv files in %FLV_FOLDER%...

    for /R %FLV_FOLDER% %%a IN (*.flv) do call :Converting_Function "%%a"
    goto :uscita



::-------------------------------------------------------------------------------------
:Converting_Function
    set infile="%~1"
    set outfile="%~dpn1.mp4"

    set outsize=0
    set insize=0
    set minsize=0

    if not %Lista%==0 goto :just_list

    echo Converting %infile% to %outfile%
    ffmpeg -v error -i %infile% -c copy -copyts %outfile%

    ::....................CHECKS........................................................
echo Errors from ffmpeg?
    if errorlevel 1 goto :error_ffmpeg

echo Do the outfile exist?
    if not exist %outfile% goto :error_exist

echo Is outfile big enough? 
    :: (say yes if outfile size > infile size*2/3)
    for /f %%S in (%outfile%) do set "outsize=%%~zS"
echo %outfile% size is %outsize%
    for /f %%S in (%infile%) do set insize=%%~zS
echo %infile% size is %insize%
    set /A "minsize=(%insize%*3)/2"
echo minsize is %minsize%

    if not %outsize% GTR %minsize% goto :error_size
    ren "%~1" "%~n1.todelete"
::               del /q %infile%
    goto :eof
:error_ffmpeg
    echo Convertion error
    pause
    if exist %outfile% del /q %outfile%
    goto :eof
:error_exist
    echo %outfile% does not exist
pause
    goto :eof
:error_size
    echo Size of %outfile% is 0
pause
    goto :eof
:just_list
    echo %infile%
    goto :eof

:uscita
pause

这是输出:

Converting "T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.flv" to "T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.mp4"
[flv @ 0000000000577320] Packet mismatch 107347968 1638 1638
Errors from ffmpeg?
Do the outfile exist?
Is outfile big enough?
"T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.mp4" size is
"T:\C++Stuffs\_PROVACONV_\Monaco - Machine_#1 - Monday Morning.flv" size is
Operando mancante.
minsize is 0
0 non atteso.
D:\ffmpeg-20170204-b1e2192-win64-static\bin>
  

Operando mancante 表示缺少操作数 0非参加表示意外0

为什么变量中没有文件大小?什么是缺少的操作数?

1 个答案:

答案 0 :(得分:2)

定义环境变量infileoutfile,文件名用双引号括起来。这不是建议的,如Why is no string output with 'echo %var%' after using 'set var = text' on command line?的答案中所解释的那样,但它是有效的,并按预期在这里工作。

获取输出文件的文件大小的命令行

for /f %%S in (%outfile%) do set "outsize=%%~zS"

在Windows命令解释程序执行之前处理,例如

for /f %S in ("C:\Path\File Name.mp4") do set "outsize=%~zS"

可以在命令提示符窗口for /?中执行时读取,for /F set (圆括号之间的字符串)解释为要处理的字符串(如果用双引号括起来)除了使用选项usebackq之外没有在这里完成。因此, FOR 将字符串C:\Path\File Name.mp4拆分为标记,使用空格/制表符作为分隔符,并将第一个标记分配给循环变量S。因此,为示例分配给S的是C:\Path\File。 Windows命令解释程序无法确定此文件的文件大小,因为此文件不存在。

解决方案是使用 FOR 而不使用选项/F

for %%S in (%outfile%) do set "outsize=%%~zS"

命令行获取输入文件的文件大小

for /f %%S in (%infile%) do set insize=%%~zS

可以替换为

set "insize=%~z1"

在命令提示符窗口call /?中运行的帮助输出解释了这个参数修饰符,用于获取在调用它时作为第一个参数传递给批处理文件的文件的大小。

运行set /?时的帮助输出解释了在算术表达式中,可以通过仅使用其名称指定环境变量而不使用%来引用环境变量的当前值或!。这甚至可以在以(开头并以匹配)结尾的命令块中工作。

带有算术表达式

的命令行
set /A "minsize=(%insize%*3)/2"

可导致insize未在执行

时定义
set /A "minsize=(*3)/2"

这解释了错误消息,因为确实缺少了乘法的左操作数。

解决方案是使用命令 SET 的帮助推荐的算术表达式。

set /A "minsize=(insize*3)/2"

此算术表达式在评估时永远不会失败。如果未定义环境变量insize,则在评估算术表达式时将其替换为0,如帮助所述。

另见Debugging a batch file

请注意,Windows命令解释程序仅支持具有32位有符号整数值的算术表达式。因此,批处理代码无法正确处理文件大小为2 GiB或更多的视频文件。