2015-01-10 3 views
0

Я использую пакетную программу для получения размера файлов, и я столкнулся с проблемой, когда размер превышает определенное количество байтов, при этом возникает ошибка, говорящая о числах, ограниченных до 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 

Но ошибка в значительной степени делает это бесполезно

+0

Не могли бы вы дать нам фрагмент кода? – Rafael

+0

Um «командный файл» на самом деле не указывает, о каком сценарии мы говорим. Кроме того, некоторый код будет приятным. –

+1

@ MarcusMüller - «пакетный файл» в «Переполнение стека» относится к командному языку Windows. Прочтите тег. – SomethingDark

ответ

0

Это можно прочитать на описании для команды set на ss64.com:

Числа все должно быть в диапазоне от 32 битовых целого числа номера (-2,147,483,648 до 2,147,483,647) для обработки больших чисел используют PowerShell или VBScript.

Таким образом, вы должны перекодировать пакетный файл как PowerShell или VBScript сценарий, чтобы иметь возможность рассчитать со значением размера файла больше, чем 2 GiB.

Можно было бы обрабатывать также большие размеры файлов за пределами LONG_MAX в пакетном файле, так как по умолчанию переменными окружения являются строки, а не целые числа.

Поэтому может быть обработана строка размера файла длиной менее 10 символов, т. Е. С 9 символами от 0 до 999999999.

Но более длинная строка размера файла может содержать целое число, большее 2147483647 и поэтому должно быть разделено на 2 целые строки.

Все операции должны выполняться с помощью двух целых строк, аналогичных тем, что программист C/C++/C# выполнял при использовании двух беззнаковых длинных переменных для 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, зависит от того, что вы хотите делать с информацией о размере файла.

0

Некоторое время назад я написал программу преобразования Decimal в 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

Смежные вопросы