webForumDet fria alternativet

Filstorlek

4 svar · 242 visningar · startad av Alpha II

Alpha IIMedlem sedan maj 20002 993 inlägg
#1

Här nedan har jag postat koden jag använder för att ta reda på en fils storlek. Den funkar... om filen inte innehåller några radbrytningar (osäker på hur, men det uppstår i alla fall avikelser när text filer är på flera rader). Finns det några andra sätt som fungerar korrekt?

long filesize(char *filename)
{
	FILE *pFile;
	pFile = fopen(filename,"r");
	if(pFile==NULL)
		return 0;

	fseek(pFile,0,SEEK_END);
	long size = ftell(pFile);
	rewind(pFile);

	return size;
}
Peter SMedlem sedan dec. 20025 483 inlägg
#2

Det fungerar korrekt eftersom radbrytningen representeras som CRLF, d.v.s. två bytes.

:)

Alpha IIMedlem sedan maj 20002 993 inlägg
#3

Nej det kan inte göra det. Programmet läser data ur en viss offset i en fil och om något innan har innehållit en radbrytning blir offseten fel med 1 / radbrytning.... :l

Alpha IIMedlem sedan maj 20002 993 inlägg
#4

Hittade detta på cplusplus.com

On files opened in text mode some translations may occur with carriage-return and line-feed characters.

Och märkte att jag hade öppnat filen i text-mode :r Nu funkar det fint :)

tmbMedlem sedan feb. 200328 inlägg
#5

Hej, Alpha II och alla andra!

Första inlägget i detta forum från undertecknad :D

Några reflektioner angående din kod bara:

Din kod fungerar men kan vara ineffektiv. Inte alla filsystem kan göra sökningar bakifrån direkt utan måste först köra igenom filen framåt för att hitta slutet och sedan backa därifrån. På små filer är inte detta märkbart men på stora filer kan det göra mycket skillnad i tid och speciellt om du gör detta på många filer. Ett effektivare sätt är att försöka använda de funktioner som finns för att ta reda på sådana här uppgifter. Nackdelen är att koden ibland inte blir lika flyttbar mellan olika OS men det kan man ju lätt fixa med #ifdef :D Det betalar sig förmodligen i slutändan för det extra arbetet.

En annan sak jag noterade var att funktionen inte stänger filen efter att den är klar med den utan gör en rewind() istället. Nu kan det ju vara by design och enda förklaringen som jag kan komma på till det är att du direkt efter att ha fått filens storlek returnerad läser från den (förmodligen efter att du allokerat en buffer för filen). Det som kan förvirra är ju att namnet på funktionen är filesize() vilket förleda en att tro att det är det enda den gör. Ett potentiellt problem jag ser med detta är att sedan klipper du ut denna funktion till något annat projekt och glömmer att den lämnar filen öppen :D Funktionen borde ha ett mer beskrivande namn alltså som kanske belyser att den har sidoeffekter, dvs gör det den ska men lämnar filen öppen efteråt.

Dessutom så returnerar den 0 om den inte kan öppna filen. Detta behöver iofs inte vara något stort problem men filer kan ju faktiskt vara 0 bytes stora. Du kan alltså på returvärdet inte veta om filen finns men har storleken 0 eller att det verkligen är ett problem med att öppna den. Den borde kanske returnera något ogiltigt värde som tex -1.

Nu nämner du ju inte för vilket OS du gjort programmet men för Linux så använder jag denna lilla funktion:

int getfilesize(
  char *filename )
{
  struct stat _stat;

  if ( stat( filename, &_stat ) )
    return -1;
  else if ( S_ISREG( _stat.st_mode ) )
    return _stat.st_size;
}

Att göra samma sak i tex Windows torde vara trivialt.

Som sagt, koden du visat här kan mycket väl vara by design men jag tänkte ändå att jag kunde ge några små, i princip allmängiltiga, kommentarer och råd från en som gått på en massa smällar genom tiderna :D Naturligtvis skall detta absolut inte tas för några sanningar satta i sten :D

126 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
123 ms — hämta tråd, inlägg och bilagor (db)