
carloslipps
¿Cuál es la diferencia entre usar las funciones fgetpos()
y fsetpos()
y usando las funciones ftell()
y fseek()
obtener y establecer una posición en un archivo?
Qué son fgetpos()
y fsetpos()
¿bueno para? ¿Por qué se usarían en lugar de ftell()
y fseek()
?
Ninguna de las respuestas anteriores es correcta – de hecho si usas fsetpos
indistintamente con fseek
podría introducir una falla de seguridad (https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255).
La razón es que el fpos_t *pos
argumento a fsetpos
en realidad no es un número entero, por lo que no se puede usar para buscar ubicaciones arbitrarias en un archivo. Por lo tanto, los únicos valores válidos son los obtenidos a partir de fgetpos
. Como dicen los documentos,
El indicador de posición del archivo interno asociado con la secuencia se establece en la posición representada por pos
que es un puntero a un fpos_t
objeto cuyo valor habrá sido obtenido previamente por una llamada a fgetpos
.
(http://www.cplusplus.com/reference/cstdio/fsetpos/)
Si todo lo que desea es la capacidad de buscar ubicaciones arbitrarias más allá del límite de 32 bits, entonces use ftello
/ fseeko
y compilar con #define _FILE_OFFSET_BITS 64
.
Bueno, en la página de manual podemos ver que ftell y fseek usan type long int para representar compensaciones (posiciones) en un archivo y, por lo tanto, pueden limitarse a compensaciones que pueden representarse en un int largo. (No se garantiza que el tipo int largo contenga valores superiores a 2**31-1, lo que limita el desplazamiento máximo a 2 gigabytes). Las funciones fgetpos y fsetpos más nuevas, por otro lado, usan un typedef especial, fpos_t, para representar las compensaciones. El tipo detrás de este typedef, si se elige correctamente, puede representar compensaciones arbitrariamente grandes, por lo que fgetpos y fsetpos se pueden usar con archivos arbitrariamente grandes. fgetpos y fsetpos también registran el estado asociado con flujos multibyte.
fgetpos() va con fsetpos(). Y ftell() va con fseek().
fgetpos() se parece prácticamente a ftell() porque ambos toman un parámetro FILE* y ambos devuelven algún tipo de posición en el archivo, aunque con un estilo ligeramente diferente. Pero escuche esto: SOLO fseek() le permite buscar desde el principio del archivo, desde su posición actual en el archivo y hacia atrás desde el final del archivo (el tercer argumento para fseek() es SEEK_SET, SEEK_CUR y SEEK_END). ). fsetpos() no hace esto. fsetpos() se limita a volver a alguna posición que obtuvo de fgetpos().
Digamos que desea leer un archivo en la memoria. ¿Cuánto montón necesitas de malloc()? Necesitas el tamaño del archivo. Y todavía tengo que encontrar alguna función en la biblioteca estándar de C que le indique el tamaño de un archivo, aunque algunos compiladores de C pueden agregar una función no estándar. Por ejemplo, Borland Turbo C tenía filelength(). Pero no he visto filelength() entre la biblioteca STANDARD C.
Entonces, lo que puede hacer es usar fseek() a 0 bytes antes del FIN del archivo. Luego use ftell() para obtener la posición en bytes, y base su cálculo para la cantidad de memoria de almacenamiento dinámico en eso.
¿Qué más podrías hacer para obtener el tamaño del archivo? Podría usar fgetc() para leer cada carácter, contando hasta llegar al final. Pero creo que usar fseek() y ftell() es mejor y más fácil.

m1tk4
No hay diferencia en la funcionalidad, aunque las interfaces se definen de manera diferente. Ambos están implementados porque ambos son parte de POSIX.
Consulte stackoverflow.com/questions/12119132/… Su respuesta es mucho mejor que la respuesta aceptada aquí.
– Mecki
24/06/2015 a las 23:39