2016-07-27 38 views
4

Ich mache ein kleines Programm wie folgt:Wie erkennen Sie nicht genügend Speicherplatz bei der Verwendung von STDIO-Dateioperationen in C/C++?

void reserve_file_space(char* file_path, size_t amount) 
{ 
    FILE* fp = fopen(file_path, "w+b"); 
    if(!fp) 
    { 
     printf("could not create a new file\n"); 
     return; 
    } 

    int fseek_ret = fseek(fp, amount, SEEK_SET); 
    if(fseek_ret != 0) 
    { 
     printf("could not seek to the desired position\n"); 
     fclose(fp); 
     return; 
    } 

    char garbage = 1; 
    size_t ret = fwrite(&garbage, 1, 1, fp); 
    if(ret != 1) 
    { 
     printf("could not write the garbage character\n"); 
    } 

    fclose(fp); 
} 

int main(int argc, char* argv[]) 
{ 
    reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30); 
    return 0; 
} 

Der freie Speicherplatz auf meinem PC ist etwa 500 MBs. In der main(), wenn ich reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 28 /*256 MB*/); aufruft gibt es eine Datei mit der genauen Größe von 256 MB erstellt. Wenn ich jedoch reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30 /*1 GB*/); aufrufe, erzeugt es die Ausgabedatei mit der Größe 0 und ohne einen Fehlerhinweis auszudrucken.

Wie kann ich herausfinden, ob der Speicherplatz ausreichend ist, um korrekt zu funktionieren?

+3

Das erste, was zu tun wäre, würde den Rückgabewert von 'fseek' und sogar' fclose' überprüfen. – kaylum

+0

@ Kaylum Ich habe. Sie alle haben 0 in den zwei Aufrufen zurückgegeben. –

+0

@ kaylum Das Überprüfen des Rückgabewertes von fclose ist sinnvoll. Vielen Dank! –

Antwort

2

Wie kann ich erfahren, ob der Speicherplatz ausreicht, um richtig zu behandeln?

Die Standardbibliothek hat hierfür keine Funktionen. Das Vorwärtssuchen (wie Sie es getan haben) ist nicht garantiert, um zu versagen, da das Dateisystem die tatsächliche Zuteilung von Plattenplatz verzögern kann, bis dieser Speicherplatz tatsächlich benötigt wird (weil Sie Daten darauf schreiben). Sie schreiben nur ein Zeichen, daher wird an dieser Stelle nur Platz für dieses eine Zeichen (und einige Metainformationen) benötigt.

Um wirklich sicher zu sein, dass Sie genug Platz haben (auch wenn Sie andere Prozesse in Betracht ziehen, die nach der Überprüfung Platz beanspruchen könnten), müssten Sie zufällige Daten der gewünschten Größe schreiben und diese dann mit Ihren tatsächlichen Daten überschreiben - Das ist kein effizienter Weg, Dinge zu tun.

Standard-Praxis ist, versuchen Sie einfach das Schreiben (ohne Vorbelegung), und überprüfen Sie, dass Schreibvorgang für den Erfolg. Dies vermeidet auch eine Prozessbeendigung, die einige "vorreservierte", aber nutzlose Dateien herumliegen lässt.

Um den verfügbaren Speicherplatz vorher zu prüfen, müssen Sie sich auf die betriebssystemspezifische Funktionalität verlassen.

Für POSIX-Systeme gibt es statvfs().

Für WinAPI gibt es GetDiskFreeSpace().

+1

Aber wie immer prüfen, ob genug Platz vorhanden ist, dann erzeugt das Ausführen einer Operation eine Race-Bedingung, bei der ein anderes Programm den freien Speicherplatz bereits genutzt hat, bevor Sie es erreichen. In [this post] (https://blogs.msdn.microsoft.com/oldnewthing/20160714-00/?p=93875) finden Sie eine Lösung für Windows, wie der Speicherplatz vorab zugewiesen werden kann, ohne in die Datei schreiben zu müssen. – RedX

+0

@RedX: Ich erwähnte diese Wettlaufbedingung, und ich erwähnte auch, warum die Vorallokation vielleicht nicht der beste Weg vorwärts ist. – DevSolar

+0

Entschuldigung, ich habe den sehr wichtigen Satz in Klammern verpasst. Der Link, den ich anbiete, bezieht sich auf einen Beitrag, in dem beschrieben wird, wie Speicherplatz unter Windows reserviert wird, ohne in die Datei schreiben zu müssen. Ich habe versucht, es in meinem ersten Kommentar zu klären. – RedX