05. februar 2003 - 10:23Der er
19 kommentarer og 1 løsning
Store filstørrelser i Delphi?
Jeg har det problem at jeg lige nu står og skal håndtere en fil på 4+ GB, og det kan jeg ikke med de funktioner jeg har nu, da de bruger Integer. Hvad kan jeg gøre for at få den rigtige filstørrelse? Det er jo lidt provokerende at få en størrelse på ca. minus 4 GB.
Det vil da ikke hjælpe noget, da jeg for det første alligevel skal have filstørrelsen returneret fra systemet. Den funktion jeg kender er gennem FindFirst hvor der benyttes TSearchRec, og dens 'Size' property er en Integer.
For det andet, så er Integer det samme som Longint, i hvert fald i den Delphi jeg benytter (Delphi 7). Begge har en range der hedder: -2147483648..2147483647
Hvis jeg bare kunne skifte typen, så brugte jeg en Int64, men det kræver jo at alle funktionerne i systemet understøtter dette, og det gør de ikke..
Det kunne man måske nok, men så er man kun garanteret op til omkring 4GB, og hvad så når filen bliver større end dette? Det er en mulig løsning, men det er ikke en der holder på lang sigt. Desværre..
Kan godt se dit problem, men ingen løsning. Nu har du ikke skrevet noget om formatet af filen, men måske kunne man komme igennem med base:offset løsnignen:
myRecord : Array[1..1024] of Byte; File of myRecord;
Dvs. du adresserer et record number og får således fat i ex. 1 kB ad gangen.
Den sad jeg faktisk selv og rodede med, men så kommer problemet, hvordan får jeg den præcise størrelse? Der er jo en fejlmargin på 0-1023 bytes i denne løsning, og selvom det måske ikke lyder af så meget, så er det dog et problem i længden når filstørrelsen skal være nøjagtig. (Ja, folk kan være ret besværlige på det område)
Dette piner mig lidt, men jeg kan ud fra koden allerede nu se at det ikke vil virke, da FileSize returnerer en Integer, ikke en Int64. Jeg har heller ikke selv en 4 GB fil, da det er noget jeg laver for en anden.
Ja, det er rigtigt nok at GetFileSize understøtter vildt store filer, men det hjælper jo ikke noget hvis FileSize returnerer en Integer, og _FileSize returnerer en Longint. De har jo samme størrelse, og samme range.. Måske en løsning der benytter de API kald som f.eks. GetFileSize, selvom jeg ikke helt kan gennemskue hvordan jeg får fat på det handle jeg skal bruge.. Har desværre ikke arbejdet vildt meget med WinAPI.
Retunere en integer, (32 bit signed), i hvertfald i D5
Hvis du skal være helt sikker på at få størelsen ud i en QWord (Quad Word), så skal du bruge En FindFirst.
altså sådan her :
function JBGetFileSize(const FileName : TFileName) : Int64; var SearchRec : TSearchRec; begin Result := -1; if FindFirst(FileName, FaAnyFile, SearchRec) = 0 then begin Result := SearchRec.FindData.nFileSizeHigh; Result := Result shl 32; Result := Result + SearchRec.FindData.nFileSizeLow; FindClose(SearchRec); end; end;
Desværre mangler Delphi en QWORD (mig bekendt) så du må nøjes med en Int64.
function JBGetFileSize(const FileName : TFileName) : Int64; var SearchRec : TSearchRec; begin Result := -1; if FindFirst(FileName, FaAnyFile, SearchRec) = 0 then begin Result := SearchRec.FindData.nFileSizeHigh shl 32 + SearchRec.FindData.nFileSizeLow; FindClose(SearchRec); end; end;
Takker Jens. Det var lige det der skulle til. Hvis jeg havde nærlæst den del af manualen havde jeg sikkert også fundet det, men skidt, nu fandt du det, og jeg kan komme videre. ^_^
Tak til alle jer andre som også kom med forslag, flere af dem meget gode. I er alle kanon! :o)
Ganske simpelt den grund, at Jens Borrisholt gav mig det svar jeg bedst kunne bruge. Det kan integreres direkte, og returnerer en Int64, nøjagtig som jeg skrev ville være lækkert.
Synes godt om
Ny brugerNybegynder
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.