Avatar billede jackass- Nybegynder
14. september 2007 - 09:47 Der er 5 kommentarer og
2 løsninger

Brugt diskplads?

Hej,

Jeg har behov for at finde ud af hvor meget plads der er brugt på et givent drev/mappe inkl. undermapper og filer rekursivt. Det kunne fx være:

C:\programmer
E:\spil
E:\
F:\film
[...]

Jeg har denne funktion:

function GetDirSize(dir: string; subdir: Boolean): Longint;
var
  rec: TSearchRec;
  found: Integer;
begin
  Result := 0;
  if dir[Length(dir)] <> '\' then dir := dir + '\';
  found := FindFirst(dir + '*.*', faAnyFile, rec);
  while found = 0 do
  begin
    Inc(Result, rec.Size);
    if (rec.Attr and faDirectory > 0) and (rec.Name[1] <> '.') and (subdir = True) then
      Inc(Result, GetDirSize(dir + rec.Name, True));
    found := FindNext(rec);
  end;
  FindClose(rec);
end;

..som jeg kalder med fx: GetDirSize('E:\spil',TRUE);

Men det virker ikke korrekt. På mit M: drev er der i.flg. windows brugt 2,57GB.. men GetDirSize() returnerer -1,53GB (minus?!?).

Det skal gøres ved at loope igennem, da DiskSize() og DiskFree() ikke virker hensigtsmæssigt på mountede netværksdrev.

Håber nogen kan hjælpe med en løsning :)

/jack
Avatar billede nielle Nybegynder
14. september 2007 - 09:57 #1
Prøv at vælge en anden heltals type end integer - svjv. er der en 64-bit version.

Fejlen opstår fordi at du får overflow.
Avatar billede pidgeot Nybegynder
14. september 2007 - 10:02 #2
Longint er kun 32-bit. Du skal bruge en Int64, da du ellers kun kan komme op på ~2GB uden at løbe ind i integer overflow.

Dertil kommer at TSearchRec.Size OGSÅ kun er 32-bit, hvilket vil sige at den heller ikke kan klare filer der er større end det. Brug i stedet rec.FindData.nFileSizeHigh og rec.FindData.nFileSizeLow sammen med lidt bitshifting.
Avatar billede jackass- Nybegynder
14. september 2007 - 10:21 #3
nielle: selfølgelig! *banke mig selv i hovedet*

pidgeot: hmm det er der noget om ja - fx. hvis man har en 5GB iso fil eller lign.

Jeg bøvler dog noget med alternativet.. Er der en af jer der er rare at konvertere funktionen til at kunne klare de store filstørrelser også, så vil jeg være meget taknemmelig? :)
Avatar billede pidgeot Nybegynder
14. september 2007 - 10:29 #4
Hvis jeg husker rigtigt:

1) Ret din returtype til Int64.
2) Skift:
Inc(Result, rec.Size);
ud med:
Inc(Result, rec.FindData.nFileSizeHigh shl 32 or rec.FindData.nFileSizeLow);

Andet skulle der vist ikke være i det, og når det er gjort, kan du klare op til 8EB - hvilket gerne skulle være nok et stykke tid endnu :P
Avatar billede jackass- Nybegynder
14. september 2007 - 11:00 #5
Det er super, tak :D

Smider I et svar begge 2, så fordeler jeg lige points'ene eftersom I begge 2 svarede nyttigt :)
Avatar billede pidgeot Nybegynder
14. september 2007 - 11:02 #6
Værsgo :)
Avatar billede nielle Nybegynder
14. september 2007 - 12:03 #7
Svar :^)

... men giv du bare de fleste til pidgeot :^)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester