2009-12-20 13 views
7

He escrito un programa que manipula archivos y, a veces, para eliminar un archivo. Así que busqué y encontré la función remove() en el archivo de encabezado stdio en C.Eliminar un archivo en C

El problema es que a veces funciona y otras no. A veces, el archivo se elimina, otro perror() muestra un mensaje que dice que se negó el permiso, pero no he especificado ningún permiso especial en el archivo. Como cuestión de hecho, el archivo ha sido creado un poco antes por otra función. ¿Alguna condición especial que deba tener en cuenta?

Aquí es la función de carga que crea el archivo:

... 
int loadF (const char *filename, plist_t pl, int size, int createFlag) { 
    FILE *pFile = NULL; 
    pnode_t pn = NULL; 
    int fsize; 
    int total; 
    int i; 

    // Get file stream. 
    pFile = fopen (filename, "rb"); 
    if (!pFile) { // File does not exist. 
     if (createFlag) { 
      if (!createF (filename)) { 
       return 0; // fail 
      } 
     } else { // abort 
      perror ("loadF:fopen"); 
      return 0; 
     } 
    } 

    // Confirm that we have opened the file stream. 
    if (!pFile) { 
     pFile = fopen (filename, "rb"); 
     if (!pFile) { 
      perror ("loadF:fopen:"); 
      return 0; 
     } 
    } 

    // Check if list has not been initialized. 
    if (pl == NULL) { 
     fclose (pFile); 
     pFile = NULL; 
     return 0; // abort 
    } 

    // Get the size of the file. 
    fseek (pFile, 0, SEEK_END); 
    fsize = ftell (pFile); 
    rewind (pFile); 

    // Check if the file is empty. 
    if (!fsize) { 
     fclose (pFile); 
     pFile = NULL; 
     return 1; // No data to load, continue. 
    } 

    // Get the total number of structures in the file. 
    total = fsize/size; 

    // Allocate memory for a node to transfer data. 
    pn = (pnode_t) malloc (sizeof (node_t) * sizeof (char)); 
    if (!pn) { 
     fclose (pFile); 
     pFile = NULL; 
     perror ("loadF:malloc"); 
     return 0; 
    } 

    // Copy from file to list every structure. 
    for (i = 1; i <= total; i++) { 
     if (feof (pFile)) { 
      printf ("OUT!"); 
      break; 
     } 
     printf ("g"); 
     fread (pn->key, size, 1, pFile); 
     printf ("f\n"); 
     if (ferror (pFile)) { 
      fclose (pFile); 
      pFile = NULL; 
      perror ("loadF:fread"); 
      return 0; 
     } 
     addfirst (pl, pn->key); // Maybe we have to allocate memory with malloc every time? 
     // Debug with a for loop in the nodes of the list to see if data are OK. 
     printf ("cid = %d\n", pl->head->key->card.cid); 
     printf ("limit = %5.2f\n", pl->head->key->card.limit); 
     printf ("balance = %5.2f\n", pl->head->key->card.balance); 
    } 

    // Close the stream. 
    if (pFile) { 
     fclose (pFile); 
     pFile = NULL; 
    } 

    // Deallocate transfer memory. 
    if (pn) { 
     free (pn); 
    } 

    // Exit 
    return 1; 
} 

Y aquí es la función que utiliza retirar:

int saveF (const char *filename, plist_t pl, int size) { 
    FILE *pFile = NULL;  // Pointer to the file structure. 
    pnode_t pn = NULL;  // Pointer to a node of a list. 


    // Delete the specified file - on success it returns 0. 
    if (remove (filename) == -1) { 
     perror ("saveF:remove"); 
     return 0; 
    } 

    // Re-create the file (but now is empty). 
    if (!createF (filename)) { 
     return 0; 
    } 

    // Get the file stream. 
    pFile = fopen (filename, "ab"); 
    if (!pFile) { 
     perror ("saveF:fopen"); 
     return 0; 
    } 

    // Check if list is not empty. 
    if (isEmpty (pl)) { 
     fclose (pFile); 
     pFile = NULL; 
     return 0;   // Abort 
    } 

    // Traverse the list nodes and save the entity that the key points to. 
    for (pn = pl->head; pn != NULL; pn = pn->next) { 
     fwrite ((pccms_t)(pn->key), size, 1, pFile); 
     if (ferror (pFile)) { 
      fclose (pFile); 
      pFile = NULL; 
      perror ("saveF:fwrite"); 
      return 0; 
     } 
    } 

    // Close the stream. 
    if (pFile) { 
     fclose (pFile); 
     pFile = NULL; 
    } 

    // Exit 
    return 1; 
} 

uso Windows XP.

+0

Se corrigió el problema, una función dejaba el puntero del archivo pfile en ocasiones abierto. Gracias por tus respuestas. – Ponty

+0

¡Bienvenido a Stack Overflow! Cuando haya recibido una buena respuesta a su pregunta, por favor "acepte" la respuesta más útil haciendo clic en el contorno de la casilla a la izquierda de la respuesta. Esto indica que recibió una respuesta que funcionó para usted. Hacer esto ayuda a aumentar su reputación en el sitio. –

Respuesta

6

No ha especificado la plataforma que está utilizando, pero en Windows, el archivo no debe abrirse cuando intenta eliminarlo. (Las cosas funcionan un poco diferente en los sistemas basados ​​en Unix y una eliminación casi siempre es posible, incluso si el archivo está abierto.)

1

Hay 3 razones: en mi opinión

  1. No tiene permiso para borrar el archivo
  2. El archivo está siendo utilizado por otra función.
  3. Debe tener permisos de escritura en el directorio donde se encuentra este archivo.
2

El caso de que no se pueda eliminar el archivo también puede depender de que otro proceso bloquee el archivo. En su situación, podría ser su función crear archivos. También depende de la plataforma que use. Si es Windows, intente utilizar Unlocker y vuelva a intentar eliminar un archivo.

-1

Te entiendo: Creas un archivo en la línea 5 y luego en la línea 7 lo borras.

En caso afirmativo: intente establecer una pequeña pausa entre esas líneas, 100 ms debería estar bien. O bien: el archivo aún está abierto. Ciérrelo e intente eliminarlo entonces.

+0

cómo retrasar en c? ¿Hay una función de retraso()? – Ponty

0

Primero haga una fclose(). De lo contrario, el archivo puede estar bloqueado. O puede que aún no se haya creado, así que agregue un retraso antes de eliminar.

Cuestiones relacionadas