Leyendo parte de un archivo en C usando fread () y fseek ()

Estoy intentando leer un archivo en un búfer en bloques de tamaño BLOCK_SIZE (actualmente igual a 1000 unsigned chars ). Inicialmente, mi código encuentra la cantidad de bloques que tendrá que leer para leer el archivo completo (generalmente 2-4), luego itera a través de un bucle for leyendo el archivo (ignore el material ” +17+filenamesize “, eso es todo Necesario para más tarde en el progtwig.

Sin embargo, solo la primera vez, cuando j=1 , realmente coloca datos en la matriz buf . En otros casos, cuando j != 1 , strlen(buf) devuelve 0 .

Creo que el problema es con el uso de fseek() para buscar la segunda parte de un archivo antes de leerlo o un problema de asignación de memoria.

Cualquier ayuda sería apreciada para que lea los caracteres 1000-1999 del archivo en la matriz buf .

Se adjunta la parte relevante del código:

 unsigned char *buf; source = fopen(localpath,"r"); temp = filesize / BLOCK_SIZE + 1; for (j=1; j <= temp; j++) { if (j == 1) { buf = (unsigned char *) malloc((sizeof(unsigned char)) * (BLOCK_SIZE + 17 + filenamesize)); fread(buf+17+filenamesize, sizeof(unsigned char), BLOCK_SIZE, source); } else if (j == temp) { buf = (unsigned char *) malloc((sizeof(unsigned char)) * (filesize + 5 - BLOCK_SIZE*(j-1))); fseek(source, BLOCK_SIZE*(j-1), SEEK_SET); // off by one warning fread(buf+5, sizeof(unsigned char), filesize - BLOCK_SIZE*(j-1), source); } else { buf = (unsigned char *) malloc((sizeof(unsigned char)) * (5+BLOCK_SIZE*(j-1))); fseek(source, BLOCK_SIZE*(j-1), SEEK_SET); // off by one warning fread(buf+5, sizeof(unsigned char), BLOCK_SIZE, source); } // do stuff with buf here buf = ""; free(buf); } 

Recomendaría verificar los resultados de fseek y fread . En particular, asegúrese de que fseek esté devolviendo 0; si no lo es, este puede ser el problema.

Siempre que fseek tenga éxito, fread debería indicarle el número total de bytes leídos.

Además, strlen no es necesariamente una cosa válida para usar, ya que asumirá que se trata de una cadena terminada en nulo. Si el primer carácter que lee es un byte 0, strlen devolverá 0. No lo está tratando como una cadena terminada en nulo (no está asignando suficiente espacio para el terminador nulo, exactamente lo que se necesita para ajustar sus datos binarios) , por lo que strlen es probablemente inapropiado.

La línea buf = ""; Me parece un bicho. Esto establecerá el puntero buf en una cadena constante que también intenta free() en la siguiente línea. Simplemente me saltearía esta línea.

También parece que se lee en el búfer con algunas compensaciones. Es decir, +5 en los dos casos posteriores. La primera parte del búfer quedará indefinida, consulte la página de manual de malloc . Así que un strlen(buf) siente indefinido para mí.

srtlen devuelve la longitud de una cadena (número de bytes antes del primer 0 bytes). Si buf [0] es 0, devuelve 0. Use el valor de retorno del fread para determinar cuántos bytes se leen realmente.

También tienes pérdida de memoria. Realiza malloc en cada iteración de bucle, pero solo se libera una vez al final.

¿Por qué usas fseek? La noción completa de “primero verifique qué tan grande es el archivo para determinar cuántas veces leer un bloque” es fundamentalmente defectuosa. Simplemente debes leer los datos hasta que no queden más datos, por ejemplo:

 while (BLOCK_SIZE == (read_count = fread (buf, sizeof * buf, count, source))
     do_stuff_with_buf (buf, read_count);

 if (ferror (fuente))
     / * Error de manejo * /;

(Este ejemplo nunca llamará a do_stuff_with_buf () en una lectura corta, pero eso es una modificación trivial).