Tengo que escribir código en C para la lectura de archivos de gran tamaño. El código es el siguiente:

int read_from_file_open(char *filename,long size)
{
    long read1=0;
    int result=1;
    int fd;
    int check=0;
    long *buffer=(long*) malloc(size * sizeof(int));
    fd = open(filename, O_RDONLY|O_LARGEFILE);
    if (fd == -1)
    {
       printf("\nFile Open Unsuccessful\n");
       exit (0);;
    }
    long chunk=0;
    lseek(fd,0,SEEK_SET);
    printf("\nCurrent Position%d\n",lseek(fd,size,SEEK_SET));
    while ( chunk < size )
    {
        printf ("the size of chunk read is  %d\n",chunk);
        if ( read(fd,buffer,1048576) == -1 )
        {
            result=0;
        }
        if (result == 0)
        {
            printf("\nRead Unsuccessful\n");
            close(fd);
            return(result);
        }

        chunk=chunk+1048576;
        lseek(fd,chunk,SEEK_SET);
        free(buffer);
    }

    printf("\nRead Successful\n");

    close(fd);
    return(result);
}

El problema que me estoy enfrentando aquí es que el argumento pasado (parámetro de tamaño) es menor que 264000000 bytes, parece ser capaz de leer. Estoy consiguiendo el aumento de los tamaños de la porción variable con cada ciclo.

Cuando me pase 264000000 bytes o más, la lectura de falla, es decir: de acuerdo a la verificación utilizado lectura devuelve -1.

Puede alguien que me señale por qué está sucediendo esto? Estoy compilando el uso de cc en el modo normal, el no uso de DD64.

  • Que sistema operativo?
  • es posible duplicar para stackoverflow.com/questions/3825896/…
  • Hay serios problemas con el código que yo pueda ver. La primera de todas las que se asigna un búfer a leer, utilizando size como el tamaño. Luego de leer la info de búfer, el uso de un tamaño fijo, dejando de lado la asigna el tamaño del búfer de leer en. Piense acerca de lo que va a pasar si size es de menos de 250. En segundo lugar, como el archivo está recién abierto, no necesita buscar el principio. En tercer lugar, a continuación, solicite a size, pero es size el número de registros en el archivo o un número de bytes? Utilice size de manera diferente a la hora de asignar el búfer.
  • En cuarto lugar, liberar el buffer dentro del bucle, pero no asignar una nueva. Esto significa que en la segunda iteración se va a leer en la memoria no. Quinto, llamando read pasará automáticamente a la posición en el archivo, usted no tiene necesidad de buscar cada vez. Sexto, cuando se lee a comprobar error, pero no para la de fin de archivo. read devuelve 0 en fin-de-archivo.
  • Y por último, no debería ser realmente el uso de read cuando la lectura de un archivo de gran tamaño. Utilizando, por ejemplo, mmap es probablemente una de las más eficaz solución, especialmente si usted está leyendo el archivo de forma secuencial.
  • Acordado en la sugerencia de utilizar mmap para la lectura de archivos de gran tamaño. También, considere la posibilidad de aumentar su paginación o memoria de intercambio o swap tamaño demasiado, para evitar errores de asignación de memoria.

InformationsquelleAutor srijeet | 2012-08-03

3 Comentarios

  1. 8

    En primer lugar, por qué usted necesita lseek() en su ciclo? read() hará avanzar el cursor en el archivo por el número de bytes leídos.

    Y, para el tema: largo, y, respectivamente, pedazo, que tienen un valor máximo de 2147483647, cualquier número mayor que el que realmente va a ser negativo.

    Desea utilizar off_t a declarar fragmento: off_t chunk, y el tamaño de size_t.
    Esa es la razón principal por la que lseek() falla.

    Y, a continuación, de nuevo, como otras personas han notado, no quiere free() su buffer dentro del ciclo.

    Nota también de que se sobrescriban los datos que ya han leído.
    Además, read() no necesariamente leer tanto como a usted le han pedido que, por lo que es mejor para el avance de la porción por la cantidad de bytes realmente leer, en lugar de la cantidad de bytes que desea leer.

    Tomando todo en lo que respecta, el código correcto debe probablemente se verá algo como esto:

    //Edited: note comments after the code
    #ifndef O_LARGEFILE
    #define O_LARGEFILE 0
    #endif
    
    int read_from_file_open(char *filename,size_t size)
    {
    int fd;
    long *buffer=(long*) malloc(size * sizeof(long));
    fd = open(filename, O_RDONLY|O_LARGEFILE);
       if (fd == -1)
        {
           printf("\nFile Open Unsuccessful\n");
           exit (0);;
        }
    off_t chunk=0;
    lseek(fd,0,SEEK_SET);
    printf("\nCurrent Position%d\n",lseek(fd,size,SEEK_SET));
    while ( chunk < size )
      {
       printf ("the size of chunk read is  %d\n",chunk);
       size_t readnow;
       readnow=read(fd,((char *)buffer)+chunk,1048576);
       if (readnow < 0 )
         {
            printf("\nRead Unsuccessful\n");
            free (buffer);
            close (fd);
            return 0;
         }
    
       chunk=chunk+readnow;
      }
    
    printf("\nRead Successful\n");
    
    free(buffer);
    close(fd);
    return 1;
    
    }

    También me tomé la libertad de la eliminación de resultado variable y todos los relacionados con la lógica, ya que, creo, puede ser simplificado.

    Edit: he notado que algunos sistemas (en particular, BSD) no tienen O_LARGEFILE, ya que no se necesita allí. Así que, he añadido un #ifdef en el principio, lo que iba a hacer el código más portable.

  2. 1

    La función lseek puede tener dificultad en el apoyo a los grandes tamaños de archivo. Trate de usar lseek64

    Por favor, compruebe el enlace para ver las macros asociadas que necesita ser definido cuando se utiliza lseek64 función.

  3. 0

    Si su equipo de 32 bits, que se le cause algún problema para leer un archivo de más de 4gb. Así que si usted está utilizando el compilador gcc de intentar utilizar la macro -D_LARGEFILE_SOURCE=1 y -D_FILE_OFFSET_BITS=64.

    Por favor revise esta enlace también

    Si usted está usando cualquier otro compilador de verificación para tipos similares de opción del compilador.

Dejar respuesta

Please enter your comment!
Please enter your name here