2011-05-13 68 views
10

Estoy trabajando en un programa simple de división/fusión de archivos en el lenguaje de programación C. El problema es que, por algún motivo, fopen devuelve NULL y, debido a eso, mi programa se bloquea en la instrucción fwrite. ¿Cómo puedo solucionar esto?¿Por qué 'fopen' devuelve un puntero NULL?

Aquí está el archivo C:

int SplitFile(char* filename, char* output, size_t size) 
{ 
    char current_file_name[256]; 
    int file_count = 0, i = 0; 
    FILE *file = fopen(filename, "rb"); 
    printf("split %s into chunks of %d named\n", filename, size); 

    if (!file) 
     return E_BAD_SOURCE; 
    else 
    { 
     output = (char *) malloc(size * sizeof(char)); 
     if (output == NULL) 
      return E_NO_MEMORY; 
     else 
     { 
      int bytes_read = 0; 
      FILE *outFile; 
      do 
      { 
       bytes_read = fread(output, sizeof(char), size, file); 
       sprintf(current_file_name, "%s%04lu\n", "part", file_count++); 
       outFile = fopen (current_file_name, "wb"); // THIS RETURNS NULL 
       fwrite(output, sizeof(char), bytes_read, outFile); //CRASHES ON THIS LINE 
      } 
      while (bytes_read > 0) 
       ; 

      //fclose(outFile); 
     } 
    } 
    fclose(file); 
    printf("...\n"); 
    return 0; 
} 
+1

Snarky - comprobar el archivo abierto antes de intentar escribir en él. La verdadera respuesta es que probablemente no tenga los permisos del sistema de archivos o que esté en una ruta de carpeta que no existe – EnabrenTane

+9

¿Qué error se almacena en 'errno'? Simplemente agregue 'if (! OutFile) perror (" fopen ");' y deje que la biblioteca le explique por qué falló. :) – sarnold

+0

in errno Estoy recibiendo fopen: argumento inválido – k787

Respuesta

9

Lo más apropiado que hacer es comprobar errno cuando fopen vuelve NULL.

Voy a adivinar que su problema es que está tratando de escribir en un sistema de archivos que no permite \n en los nombres de archivo, pero también podría ser un problema de permisos.

+1

Lo más apropiado es comprobar errno cuando fopen devuelve NULL. Probablemente quiso decir fopen en lugar de fwrite. –

+0

cuando comento el sprintf y hago esto; outFile = fopen ("part000", "wb"); funciona bien. – k787

+0

@Windows: ¡Vaya! Gracias. – Gabe

0

¿Está abierto para escritura devuelve NULL en la primera ejecución?

Me di cuenta de que mientras tanto mantiene archivos abiertos para escribir pero no los cierra.

intenta agregar fclose (OUTFILE) después fwrite:

outFile = fopen (current_file_name , "wb");  
fwrite(output, sizeof(char), bytes_read, outFile); 
fclose(outFile) 

Es posible abrir más archivos de su sistema operativo permite.

+0

Sí, pensé lo mismo y cerré los archivos, pero no funcionó – k787

1

Como dijo Gabe, su problema es una nueva línea en el nombre de archivo que es ilegal en Windows.

Pero, ¿por qué no utiliza split de GNU Core Utilities? Instalado por defecto en Unices/Linux, se puede descargar para Windows desde GnuWin32 project.

split --suffix-length=4 --numeric-suffixes --bytes=1M - part < filename 
5

Hay muchas razones fopen puede volver NULL incluyendo (pero no limitados a):

  • El archivo no existe
  • El archivo se abre en un modo que no lo hace permitir que otros accesos
  • La red está abajo
  • El archivo existe, pero que no tiene permisos
  • Existe un archivo con el nombre que proporcionó, pero el directorio actual del proceso no es el que esperaba, por lo que la ruta de acceso relativa no puede encontrar y abrir el archivo.

La manera de averiguar quién es responsable es profundizar en el código errno.

Sin embargo, solo porque resuelva este error en particular no significa que pueda asumir fopen nunca devolverá NULL. Cuando se trata de operaciones de E/S, su código simplemente tiene que esperar una falla. No es posible predecir el éxito de las operaciones de E/S, y siempre pueden fallar.

+0

¿Qué tal si se queda sin espacio? ¿Eso no lo haría volver NULL? (sé que usted dijo "no limitado a" mi pregunta no es retórica) – Nande

+0

@Nande: 'fopen()' que crea un nuevo archivo puede o no tener éxito en un disco completo. Si el directorio no necesita expandirse (y no está fuera de inodos), puede tener éxito, pero fallarán los siguientes 'fwrite()' (** o ** 'fclose()'!). –

1

Significa que el archivo puede no existir o que se produjo algún error al acceder a un archivo como "Solo lectura" o "Protegido contra escritura", por lo que fopen devolverá 0 (un puntero NULL). En caso de éxito, devolverá un puntero de archivo como controlador.

fp=fopen("c:\\ABC.txt", "r"); no puede ser lo mismo que fp=fopen("c:\\abc.txt", "r");.

Use // en lugar de \\ en un entorno Linux.

P.S .: En los nombres de archivo de los sistemas operativos Linux y Unix son entre mayúsculas y minúsculas.

0

En Unix, para fopen(), no hay ninguna razón para anteponer ./ a un nombre de archivo pasado a fopen().

0

En mi caso, estaba leyendo el mismo archivo de nuevo en un bucle while y olvidé cerrarlo.

que utiliza una función para leer el archivo y encontrar un donante compatible y la función tenido una declaración return; que termina la función antes de hacer fclose(fp): D

Cuestiones relacionadas