Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Неправильный объем при рекурсивном подсчете


Автор: Тутанхамец 24.3.2006, 07:32
Уважаемые! Вот у меня есть такой код, с которым я уже рискнул вчера к вам обратиться (и не напрасно). Эта функция находит все файлы, но сколько места они занимают - считает неправильно. Для папки весом в 4 гига выдает 161 мегабайт с копейками... Почему так?

Код

procedure TAC.CountFiles(sDir :string);
var
    F:TSearchRec;
    g:integer;
    s:string;
begin
    g:=FindFirst(sdir+'\*',faanyfile,f);
    while g=0 do begin
        if (f.name<>'.') and (f.name<>'..') then begin

            if (f.Attr and fadirectory)=fadirectory then begin
                countfiles(sdir+'\'+f.name);
                inc(folderscount); end
            else begin
                inc(filescount);
                totalsize:=totalsize+cardinal(f.size);
            end;
        end;
            g:=FindNext(f);

    end;
    FindClose(f);
    if assigned(FCountEvent) then countevent(self,filescount,folderscount,totalsize);
end;


Буду очень признателен.

Автор: Dian 24.3.2006, 07:43
А чему изначально равно totalsize?

Автор: Тутанхамец 24.3.2006, 07:47

Нулю. Оно обнуляется при создании класса TAC.

Автор: Snowy 24.3.2006, 09:27
А оно у тебя случайно не integer?
В интегер больше 4 гигового значения не засунешь...
Нужно int64
Добавлено @ 09:28
P.S. Кстати, ты считаешь общий объем файлов, а не место, которое они занимают на диске...

Автор: Guedda 24.3.2006, 09:48
Зачем Cradinal-ить?
Все гораздо проще делается... У меня такая схема примерно стоит:
Код

procedure TAC.CountFiles(sDir :string);
var
    F:TSearchRec;
    g:integer;
    s:string;
begin
    g:=FindFirst(sdir+'\*',faanyfile,f);
    while g=0 do begin
        if (f.name<>'.') and (f.name<>'..') then begin
            if (f.Attr and fadirectory)=fadirectory then begin
                countfiles(sdir+'\'+f.name);
                inc(folderscount); end
            else begin
                inc(filescount);
                totalsize:=totalsize+f.size; //totalsize : Int64, как говорил Snowy;
            end;
        end;
            g:=FindNext(f);
    end;
    FindClose(f);
    if assigned(FCountEvent) then countevent(self,filescount,folderscount,totalsize);
end;

Все прекрасно работает. У меня 5-гиговую папку проверила. И все ОК.

Автор: Тутанхамец 24.3.2006, 10:10
Насчет объема, а не места на диске - это я понимаю. Так и надо.
Насчет cardinal-то я сообразил. Не знаю, зачем я кардиналю, случайно вышло smile Там еще s болтается не по делу. Только вот это ничего не меняет. И totalsize у меня cardinal, а не integer. А считает неправильно. smile
Добавлено @ 10:19
Опс! Ошибочка. Я думал, что cardinal - это беззнаковый int64.
Учел. Totalsize:int64.
Да! Это была ошибка переполнения. Он доходил до предельного значения, а потом результат шел неверный.

Всем огромное спасибо! smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)