2010-03-02 7 views
8

Ich habe eine einfache Funktion gemacht, die eine Dateigröße hat.Wie bekomme ich eine Dateigröße, die größer als 4 GB ist?

int file_size(char * filename) 
{ 
    int size; 
    struct stat st; 

    stat(filename, &st); 
    size = st.st_size; 

    return size; 

}//file_size 

Es funktioniert gut, aber wenn ich eine Datei, die Größe größer als 4 GB ist als ich eine negative Zahl zurück, und natürlich bekommen dies ist nicht die richtige Dateigröße. Wie kann ich eine so große Dateigröße bekommen? Ich denke, dass der Rückgabewert alles andere wie int sein sollte, aber ich weiß nicht was, und ich glaube nicht, dass das mein Problem lösen würde.

Danke,

kampi

Update:

Hallo!

Ich fand die Lösung. Ich muss __stat64 verwenden. Ich habe meine Funktion geändert und jetzt wird die tatsächliche Größe abgerufen. Ich habe es mit einer 8 GB großen Datei getestet.

unsigned long long int file_size(char * filename) 
{ 
    unsigned long long int size; 
    struct __stat64 st; 

    __stat64(filename, &st); 
    size = st.st_size; 

    return size; 

}//file_size 

Und ein Hinweis:

Wenn ich printf verwendet, i "% I64d" verwenden musste, um es auszudrucken.

+0

Was passiert, wenn Sie 'int' in' off_t' ändern, oder wenn das nicht verfügbar ist, 'size_t'? Sowohl im Rückgabetyp als auch in der Angabe der Größe. –

Antwort

3

Sie können wahrscheinlich _stat64 verwenden.

+0

Vielen Dank, das war der einfachste Weg, um mein Problem zu lösen. – kampi

5

Sie können die Funktion Win32 GetFileSizeEx verwenden.

HANDLE aFile = CreateFile 
(
    filename, 
    FILE_READ_ATTRIBUTES, 
    0, 
    NULL, 
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL, 
    NULL 
); 

if (aFile != INVALID_HANDLE_VALUE) 
{ 
    long long aSize; 
    GetFileSizeEx(aFile, &aSize); 

    CloseHandle(aFile); 
    return aSize; 
} 
else 
    return -1; 
+0

Der einzige Nachteil dabei könnte (nicht sehr sicher) sein, dass es schwierig sein könnte, Posix-Aufrufe mit Win32-Aufrufen innerhalb desselben Prozesses zu mischen und zu vergleichen. Es sieht so aus, als würde das OP von einem Unix-Hintergrund kommen und nur Posix-Aufrufe verwenden wollen. –

0

denke ich, ist Problem wegen der Dateigröße mehr als INT_MAX, so dass es Ihnen negative Werte gibt.

Wahrscheinlich können Sie Cast für lange Datentyp eingeben, kann es funktionieren.

Sonst verwenden, fseek, ftell Funktion. subtrahiere dann den Enddateizeiger vom Startdateizeiger. Es gibt Ihnen auch die Dateigröße. (Anzahl der Bytes).

1

st_size wird so lange in wchar.h definiert, so dass Sie wahrscheinlich mit lange, statt int

struct stat { 
    .... 
    _off_t  st_size; 
    .... 
} 

.... 

typedef long _off_t; 

sein kann wie dieses

long file_size(char * filename) 
{ 
    long size; 
    struct stat st; 

    stat(filename, &st); 
    size = st.st_size; 

    return size; 

}//file_size 
+1

Kein Grund, warum Sie "unsigned" nicht vorgeben können, da die Dateigröße wahrscheinlich nicht negativ ist. –

+2

Wenn die Kürzung in st.st_size passiert, bin ich neugierig, wie es in dieser Situation hilft, es einem langen zuzuteilen. – Arun

3

In einem solchen könnten versuchen, Fälle, Rückgabewert von stat() möglicherweise -1 und errno auf EOVERFLOW festgelegt.

Der Mann Seite für stat auf meiner (64 x86 Maschine Bit) sagt:

EOVERFLOW

(stat()) bezieht sich Pfad zu einer Datei, deren Größe nicht in der Art dargestellt werden kann aus_t.Dies kann auftreten, wenn eine Anwendung auf einer 32-Bit-kompilierten Plattform ohne -D_FILE_OFFSET_BITS = 64 ruft stat() für eine Datei, deren Größe überschreitet (2 < < 31) -1 Bits.

Verwandte Themen