2012-06-13 30 views
8

¿Cómo puedo determinar si un archivo está vacío? El archivo se abre con un programa en C que se ejecuta en la plataforma de Windows. Quiero abrir un archivo en el modo de agregar y, si está vacío, primero imprimir un encabezado en él.¿Cómo puedo determinar si un archivo está vacío?

// 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); 

que estaba esperando ftell para devolver el tamaño actual del archivo si el archivo no estaba vacío, lo cual se debe a que el código anterior se enlaza.

Sin embargo, ftell siempre devuelve 0 y el encabezado se imprime varias veces.

Sé que podría fopen con r y utilizar fseek/ftell/fclose y luego otra vez con fopena+, pero yo creo que es posible hacer esto sin necesidad de abrir y cerrar el archivo varias veces.

+0

Las operaciones de E/S de archivos difieren entre sistemas operativos, entonces ... ¿con qué sistema operativo está trabajando? –

+1

'No se puede abrir el archivo de salida CSV ...' es el ejemplo canónico de un mensaje de error * malo *. Incluya el nombre del archivo real y la razón del error ('man perror' y' man strerror'). –

+0

@EitanT: eso es para Windows –

Respuesta

6

En realidad, cuando fopen ing un archivo en modalidad de apertura, el puntero de archivo está inicialmente en el inicio del archivo . Se mueve hasta el final tan pronto como escribe algo o usa fseek.

Solo necesitaba agregar fseek(report_csv, 0, SEEK_END); antes de mi if (!ftell(report_csv)).

Veamos esto.
Código:

#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; 
} 

de salida:

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. 
2

Al abrir un archivo con fopen con el modo a+, todas las operaciones de escritura se realiza al final del archivo. Puede volver a colocar el puntero interno en cualquier parte del archivo para leer, pero las operaciones de escritura lo moverán de nuevo al final del archivo. La posición inicial del puntero para leer está al principio del archivo.

Por lo tanto, debe llamar al fseek(pFile, 0, SEEK_END) en su puntero FILE.

+0

¡Sí, eso es correcto! Pensé esto hace solo diez minutos. Muchas gracias. –

+0

No actualicé la página ... lo siento :) –

Cuestiones relacionadas