【问题标题】:Batch Files too Big to Read批处理文件太大而无法读取
【发布时间】:2015-01-10 14:59:01
【问题描述】:

我正在使用批处理程序来获取文件的大小,我遇到了一个问题,当大小超过一定数量的字节时,它会出现一个错误,指出数字限制为 32 位精度.我已经尝试通过将其设置为 kibobits 和 mebibits 来解决此问题,但是一旦程序确定文件具有特定大小,它就会拒绝执行任何操作。

@echo off
set kbno=0
set mbno=0
set var=(this would be the output of the file size)
:kbcheck
if /i %var% GTR 1024 (
goto 10kbcheck
) else (
goto setsize
)
:10kbcheck
if /i %var% GTR 10240 (
goto 50kbcheck
) else (
set /a kbno+=1
set /a var=%var%-1024
goto kbcheck
)
:50kbcheck
if /i %var% GTR 51200 (
goto 100kbcheck
) else (
set /a kbno+=10
set /a var=%var%-10240
goto kbcheck
)
:100kbcheck
if /i %var% GTR 102400 (
goto 500kbcheck
) else (
set /a kbno+=50
set /a var=%var%-51200
goto kbcheck
)
:500kbcheck
if /i %var% GTR 512000 (
goto mbcheck
) else (
set /a kbno+=100
set /a var=%var%-102400
goto kbcheck
)
:mbcheck
if /i %var% GTR 1048576 (
set /a mbno+=1
set /a var=%var%-1048576
goto kbcheck
) else (
set /a kbno+=500
set /a var=%var%-512000
goto kbcheck
)
:setsize
set size=%var%
echo %mbno% mebibits %kbno% kibibits %size% bits
pause

但是这个错误几乎使这个没用

【问题讨论】:

  • 你能给我们一个你的代码的sn-p吗?
  • 嗯“批处理文件”并没有真正指定我们正在谈论的脚本类型。另外,一些代码会很好。
  • @MarcusMüller - Stack Overflow 上的“批处理文件”指的是 Windows 命令语言。阅读标签。
  • 您使用的是什么操作系统?您可能可以在批处理代码中添加 PowerShell 单行代码,因为它可以处理比批处理上限 2^32 大得多的数字。
  • @SomethingDark Windows 7

标签: file batch-file size byte


【解决方案1】:

可以在ss64.com上的命令set的描述中阅读:

所有数字都必须在 32 位有符号整数范围内(-2,147,483,648 到 2,147,483,647)才能使用 PowerShell 或 VBScript 处理更大的数字。

因此,您必须将批处理文件重新编码为 PowerShell 或 VBScript 脚本,以便能够使用大于 2 GiB 的文件的大小值进行计算。

在批处理文件中也可以处理超过LONG_MAX 的大文件,因为默认环境变量是字符串而不是整数。

因此可以直接处理长度小于 10 个字符的文件大小字符串,即最多 9 位 - 0 到 999999999。

但较长的文件大小字符串可能包含大于 2147483647 的整数,因此必须拆分为 2 个整数字符串。

所有操作都必须使用这 2 个整数字符串来完成,类似于 C/C++/C# 程序员在使用 2 个无符号长变量进行 64 位操作时所做的操作。

这是一个小批处理脚本,演示如何检查一个数字是否太大而无法作为有符号 32 位整数处理。

@echo off
setlocal
set "Number=0"
set /P "Number=Please enter an unsigned integer number: "

set "DigitsLow=%Number:~-9%"
if "%DigitsLow%"=="%Number%" goto MaxBits31

set "DigitsHigh=%Number:~0,-9%"

if %DigitsHigh% EQU 1 goto MaxBits31
if %DigitsHigh% EQU 2 (
    if %DigitsLow% LEQ 147483647 goto MaxBits31
)

echo %Number% must be processed special because this
echo number is too large for a signed 32-bit integer.
goto EndBatch

:MaxBits31
echo %Number% can be processed as signed 32-bit integer.

:EndBatch
endlocal

注意:此演示批处理代码不包含任何代码来检测错误的用户输入,例如用户输入的数字、负数或真正的长数字序列。

如何最好地处理值大于 2^31-1 的文件大小取决于您要如何处理文件大小信息。

【讨论】:

    【解决方案2】:

    前段时间我写了一个小数到 PowerOf1024 的转换程序来管理这个转换。 Here it is:

    @echo off
    setlocal EnableDelayedExpansion
    
    rem DecimalToPowerOf1024.bat bigNumber
    rem Decimal to power-of-1024 base conversion of an unlimited size decimal number 
    rem Antonio Perez Ayala
    
    rem Values to try:  1024  1048576  1073741824  1099511627776  1125899906842624
    rem 1152921504606846976  1180591620717411303424  1208925819614629174706176
    rem 1237940039285380274899124224  1267650600228229401496703205376
    
    rem Divide the number in 9-digits groups, eliminating left zeros in each group
    set number=%1
    set groups=0
    :nextGroup
       set group=%number:~-9%
       for /L %%a in (1,1,8) do if "!group:~0,1!" equ "0" set group=!group:~1!
       set /A groups+=1
       set group[%groups%]=%group%
       set number=%number:~0,-9%
    if defined number goto nextGroup
    
    rem Convert the 9-digits groups to power-of-1024 values
    set /A bitPos=0, PowerOf1024=0, PowerOf1024[0]=0
    :nextBinaryDigit
       rem Divide the 9-digits groups by 2 
       set carry=0
       for /L %%i in (%groups%,-1,1) do (
          set /A term=carry*1000000000+group[%%i], group[%%i]=term/2, carry=term%%2
       )
       rem Insert remainder in current PowerOf1024 value, in right-to-left order
       set /A "PowerOf1024[%PowerOf1024%]+=carry<<bitPos, bitPos+=1"
       rem If current PowerOf1024 value completed: pass to next one
       if %bitPos% equ 10 set /A bitPos=0, PowerOf1024+=1 & set PowerOf1024[!PowerOf1024!]=0
       rem If last (most significant) group was completely converted: eliminate it
       if !group[%groups%]! equ 0 set /A groups-=1
       rem And pass to convert the rest of 9-digits groups
    if %groups% gtr 0 goto nextBinaryDigit
    
    rem Remove the last (most significant) PowerOf1024 value if it is zero
    if !PowerOf1024[%PowerOf1024%]! equ 0 set "PowerOf1024[%PowerOf1024%]=" & set /A PowerOf1024-=1
    
    set PowerOf1024
    

    例如:

    C:\> DecimalToPowerOf1024.bat 1267650600228229401496703205376
    PowerOf1024=10
    PowerOf1024[0]=0
    PowerOf1024[10]=1
    PowerOf1024[1]=0
    PowerOf1024[2]=0
    PowerOf1024[3]=0
    PowerOf1024[4]=0
    PowerOf1024[5]=0
    PowerOf1024[6]=0
    PowerOf1024[7]=0
    PowerOf1024[8]=0
    PowerOf1024[9]=0
    

    你可以使用这个转换然后得到文件大小为:%PowerOf1024[3]% GB + %PowerOf1024[2]% MB + %PowerOf1024[1]% KB + %PowerOf1024[0]% bytes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 2016-12-29
      • 2018-04-06
      • 1970-01-01
      • 1970-01-01
      • 2019-05-31
      • 1970-01-01
      相关资源
      最近更新 更多