赵家小少爷 2019-12-25
目录
背景: 前前段时间,做文件操作处理时,有这么一个场景: window 下需要对某固定目录下的文件及其他文件进行拷贝操作, 至目标对象 外置存储设备(U盘或移动硬盘),且需要一定大小的存储量。
问题: 其主要问题不在文件拷贝操作,而是对外置存储设备的处理(主要是对磁盘大小的判断,也就是数字的比较)。首先批处理的数字有一定范围,其次超出范围的比较情况还有不同。
解决: 其一则是正面刚(截取操作再比较),其二则是绕过换其他方法(调 PowerShell 处理)
注:范围值 正负 2^31-1
1.下图为批处理数字比较的情况:两个值都超出范围的比较,结果相反
2.以下为当时的脚本(后面磁盘大小的计算实在不知道咋怎,用了 PowerShell ):
@echo off & setlocal enabledelayedexpansion rem ========================================================= rem == The tools develop for copy files to external disk == rem == author: by zzw == rem == datetime: 2019.07.1 == rem ========================================================= @rem chcp 936 ::更换默认编码 @rem 源路径 set srcPath=F:\zzwTest @rem 本地磁盘驱动器: C:\ D:\ E::HasDrive for /f "tokens=1,* delims= " %%i in ('fsutil fsinfo drives') do ( set d=%%j set d=!d:\=! @rem echo !d!. 遍历磁盘信息是否包含 移动 字符 for %%a in (!d!) do ( fsutil fsinfo driveType %%a | findstr "移动" >nul && set driver=%%a ) @rem 移动硬盘会被指定为固定驱动器.需要去除本地磁盘 if not defined driver ( set d=!d:C:=! set d=!d:D:=! set d=!d:E:=! set d=!d: =! set driver=!d! if "!d!"=="" ( call :Tip1 ) else ( call :Tip1 ZZW ) ) goto DriverSpace ) :DriverSpace if defined driver ( @rem 包含 可用字节总数 的行,取第一行 for /f "tokens=1,2 delims=:" %%i in ('fsutil volume diskFree %driver% ^|findstr "可用字节总数"') do ( set free=%%j @rem echo !free! | findstr "(" && set free=!free:*(=! & set free=!free:^)=! || set free=!free: =! for /f "tokens=1 delims= " %%x in ("!free!") do ( set free=%%x ) @rem calculate disk size. multiplier of 1.1 @rem debug: set free=1048576000 if !free! LSS 1126 ( call :Tip3 1 B ) if !free! LSS 1153433 ( call :Tip3 1024 KB ) if !free! LSS 1181116006 ( call :Tip3 1024*1024 MB ) call :Tip3 1024*1024*1024 GB :Below @rem 批处理数值范围在正负 2^31-1 = 2147483647 set total=!free!t if "!total:~10!"=="" ( @rem echo 小于 10 位数 0.93GB=999999999B 0.5GB=536870912B if "!total:~8!"=="" ( call :Tip2 [10MB] ★★★警告★★★) if "!total:~9!"=="" ( call :Tip2 [100MB] ★★★警告★★★) set totalN=!total:~0,9! if !totalN! LSS 104857600 ( call :Tip2 [100MB] ★★★警告★★★) if !totalN! LSS 262144000 ( call :Tip2 [250MB] ★★★警告★★★) if !totalN! LSS 536870910 ( call :Tip2 [500MB] ★★★警告★★★) call :Tip2 [1GB] ) if "!total:~10!"=="t" ( @rem echo 等于 10 位数 6GB=6442450944B set totalA=!total:~0,10! if !totalA! LSS 1048576000 ( call :Tip2 [1GB] ) if !totalA! LSS 1610612735 ( call :Tip2 [1.5GB] ) if !totalA! LSS 2147483646 ( call :Tip2 [2GB] ) set totalB=!total:~0,9! if !totalB! LSS 268435456 ( call :Tip2 [2.5GB] ) if !totalB! LSS 322122547 ( call :Tip2 [3GB] ) if !totalB! LSS 429496729 ( call :Tip2 [4GB] ) if !totalB! LSS 536870912 ( call :Tip2 [5GB] ) if !totalB! LSS 644245094 ( call :Tip2 [6GB] ) ) goto ReSelect ) ) :Tip1 color 0b & echo, echo 请确保外置 [U盘] 或 [移动硬盘] 插入成功!!!& echo, if not "%1"=="" ( echo 磁盘识别错误,请联系开发者 ----^> %1& echo, ) goto End :Tip2 color 0b & echo, echo 请确保 %driver% 盘空间至少 6GB 可用 & echo, if not "%2"=="" echo %2 echo 注意 %driver% 盘空间小于 %1 ,不建议继续操作,默认 N echo 若继续将可能导致部分文件复制失败!!! echo, set /p confirm=请确认是否要继续(N/Y)_^>^> if /i %confirm%==y goto ReSelect goto End :Tip3 set /p =◆ %driver% 磁盘可用空间(约)为: <nul @rem powershell -c "[String]$i=!free!/(%1);if($i.contains('.')) {$s=$i.split('.'); $s[0],$s[1].substring(0,3)+'%2' -join('.')} else {$i+'%2'}" powershell -c "[String]$i=!free!/(%1);if($i.contains('.')) {$s=$i.split('.'); $s[0]+'.'+$s[1].substring(0,3)+' %2'} else {$i+'%2'}" goto Below :ReSelect color 0a echo, echo *********该工具将拷贝所选目录文件至 %driver% 盘设备******** echo, echo 请在下列选项中选择需要操作的路径(如: 1 、2 、3 ) echo, echo ========================================================== set a=0 for /f %%i in ('dir /b /ad "%srcPath%"') do ( set /a a+=1 echo [!a!] %%i ) echo, echo ========================================================== set a=0 set /p number=请输入: for /f %%i in ('dir /b /ad "%srcPath%"') do ( set /a a+=1 if !a!==%number% set testResult=%%i & echo, & echo 你的选择是 %%i ) if not defined testResult ( color 04 echo, echo 请选择正确的选项! echo 请按任意键重新选择! pause >nul & cls & goto ReSelect ) echo, echo "=====可以开始操作了======" :End pause
cmd 命令行中 powershell /?
先查看简要帮助文档
若要运行PowerShell 脚本或者命令,首先使用 PowerShell 需要开启相关权限,如下操作即可:
@echo off @rem set the execution mode of the PowerShell set flag=1 @rem -c ---> -Command powershell -c "Get-ExecutionPolicy" |findstr "Restricted" >nul && set flag=0 if %flag% == 0 ( powershell -c "Set-ExecutionPolicy RemoteSigned" echo Allowed to use powershell ) :: 里面的冒号需要转义,才能正常输出 powershell -c "if(2147483648 -lt 2147483649){\"true\"}else{\"false\"}"
待续....