2012-06-13 14 views
8

Come determinare se un file è vuoto? Il file viene aperto da un programma C in esecuzione sulla piattaforma Windows. Voglio aprire un file in modalità append e, se vuoto, prima stamparne un'intestazione.Come posso determinare se un file è vuoto?

// Open CSV & write header 
report_csv = fopen("SNR.csv", "a+"); 
if (!report_csv) { 
    fprintf(stderr, "Unable to open CSV output file..."); 
    return -1; 
} 
if (!ftell(report_csv)) { 
    fprintf(report_csv, "Column A;Column B;Column C\n"); 
} 
// ... print data to file 
fclose(report_csv); 

mi aspettavo ftell per restituire la dimensione del file corrente se il file non era vuoto, che avviene perché il codice di cui sopra è in loop.

Tuttavia, ftell restituisce sempre 0 e l'intestazione viene stampata più volte.

So che potrei fopen con r e utilizzare fseek/ftell/fclose e poi fopen di nuovo con a+, ma penso che sia possibile farlo senza aprire e chiudere il file più volte.

+0

Le operazioni di I/O file differiscono tra i sistemi operativi, quindi ... qual è il sistema operativo con cui si sta lavorando? –

+1

'Impossibile aprire il file di output CSV ...' è l'esempio canonico di un messaggio di errore * errato *. Includere il nome del file effettivo e il motivo dell'errore ('man perror' e' man strerror'). –

+0

@EitanT: questo è per Windows –

risposta

6

In realtà, quando fopen ing un file in modalità accodamento, il puntatore del file è inizialmente all'inizio del file . Si sposta alla fine di esso appena scrivi qualcosa o usa fseek.

Ho solo bisogno di aggiungere fseek(report_csv, 0, SEEK_END); prima del mio if (!ftell(report_csv)).

Controlliamo questo.
Codice:

#include <stdio.h> 

int main(int argc, char **argv) { 
    FILE *test; 
    size_t size; 
    char buf[100]; 

    /* Truncate file */ 
    test = fopen("test", "w"); 
    if (!test) { 
     fprintf(stderr, "Cannot open file `test`!\n"); 
     return 1; 
    } 

    /* Write something */ 
    fprintf(test, "Something. "); 
    fclose(test); 

    /* Open in append */ 
    test = fopen("test", "a+"); 
    if (!test) { 
     fprintf(stderr, "Cannot open `test` in append mode!\n"); 
     return 1; 
    } 

    /* Try to get the file size */ 
    size = ftell(test); 
    printf("File pointer is: %d\n", size); 
    fseek(test, 0, SEEK_END); 
    size = ftell(test); 
    printf("After `fseek(test, 0, SEEK_END)`, the file pointer is: %d\n", size); 

    /* Append */ 
    fprintf(test, "And that. "); 
    fclose(test); 

    /* Same without fseek */ 
    test = fopen("test", "a+"); 
    if (!test) { 
     fprintf(stderr, "Cannot open `test` in append mode!\n"); 
     return 1; 
    } 
    fprintf(test, "Hello! "); 
    size = ftell(test); 
    printf("File size is now: %d\n", size); 
    fclose(test); 

    /* Try to read */ 
    test = fopen("test", "r"); 
    if (!test) { 
     fprintf(stderr, "Unable to open `test` for reading!\n"); 
     return 1; 
    } 
    printf("File contents:\n\t"); 
    while (test && !feof(test)) { 
     fgets(buf, sizeof(buf), test); 
     printf("%s", buf); 
    } 

    /* Cleanup & exit */ 
    fclose(test); 
    printf("\n\nExiting.\n"); 

    return 0; 
} 

uscita:

File pointer is: 0 
After `fseek(test, 0, SEEK_END)`, the file pointer is: 11 
File size is now: 28 
File contents: 
     Something. And that. Hello! 

Exiting. 
1

È possibile chiamare _stat() e ottenere il valore st_size in struct _stat (non è necessario aprire il file).
dichiarata in sys/types.h seguito da sys/stat.h
Non lo so di programmazione di Windows, ma può aiutare a: http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx

2

Quando si apre un file con fopen con la modalità a+, tutte le operazioni di scrittura sarà effettuata alla fine del file. È possibile riposizionare il puntatore interno in qualsiasi punto del file per la lettura, ma le operazioni di scrittura lo spostano nuovamente alla fine del file. La posizione iniziale del puntatore per la lettura è all'inizio del file.

Quindi è necessario chiamare un fseek(pFile, 0, SEEK_END) sul puntatore FILE.

+0

Sì, è vero! L'ho pensato solo dieci minuti fa. Molte grazie. –

+0

Non ha aggiornato la pagina ... scusa :) –

Problemi correlati