lenguaje - manejo de archivos en c
¿Cuál es la razón fundamental para tomar el tamaño de fread/fwrite y contar como argumentos? (6)
Aquí, déjame arreglar esas funciones:
size_t fread_buf( void* ptr, size_t size, FILE* stream)
{
return fread( ptr, 1, size, stream);
}
size_t fwrite_buf( void const* ptr, size_t size, FILE* stream)
{
return fwrite( ptr, 1, size, stream);
}
En cuanto a una justificación para los parámetros de fread()
/ fwrite()
, he perdido mi copia de K & R hace mucho tiempo, así que solo puedo adivinar. Creo que una posible respuesta es que Kernighan y Ritchie simplemente pensaron que la realización de E / S binarias se haría de forma más natural en arreglos de objetos. Además, pueden haber pensado que la E / S de bloques sería más rápida / más fácil de implementar o lo que sea en algunas arquitecturas.
Aunque el estándar C especifica que fread()
y fwrite()
se implementen en términos de fgetc()
y fputc()
, recuerde que el estándar entró en vigencia mucho después de que C definiera C y que las cosas especificadas en el estándar podrían no han estado en las ideas originales de los diseñadores. Incluso es posible que las cosas que se dicen en "El lenguaje de programación C" de K & R no sean las mismas que cuando se diseñó el lenguaje por primera vez.
Finalmente, esto es lo que PJ Plauger tiene que decir sobre fread()
en "The Standard C Library":
Si el argumento de
size
(segundo) es mayor que uno, no puede determinar si la función también leyó elsize - 1
caracteres adicionales más de lo que informa. Como regla general, es mejor llamar a la función comofread(buf, 1, size * n, stream);
en lugar defread(buf, size, n, stream);
Básicamente, él está diciendo que la fread()
está rota. Para fwrite()
señala que, "los errores de escritura son generalmente raros, por lo que esta no es una deficiencia importante", una declaración con la que no estoy de acuerdo.
Tuvimos una discusión aquí en el trabajo con respecto a por qué fread y fwrite toman un tamaño por miembro y cuentan y devuelven la cantidad de miembros leídos / escritos en lugar de simplemente tomar un buffer y tamaño. El único uso que podríamos hacer es si se quiere leer / escribir una matriz de estructuras que no son divisibles por la alineación de la plataforma y, por lo tanto, se han rellenado, pero eso no puede ser tan común como para justificar esta elección. en diseño.
Desde FREAD (3) :
La función fread () lee los elementos nmemb de datos, cada tamaño de bytes, desde la secuencia apuntada por la corriente, almacenándolos en la ubicación dada por ptr.
La función fwrite () escribe nmemb elementos de datos, cada tamaño de bytes de longitud, en la secuencia a la que apunta el flujo, obteniéndolos de la ubicación dada por ptr.
fread () y fwrite () devuelven el número de elementos leídos o escritos con éxito (es decir, no el número de caracteres). Si se produce un error, o se llega al final del archivo, el valor de retorno es un recuento breve de elementos (o cero).
Creo que es porque C carece de sobrecarga de funciones. Si hubiera alguno, el tamaño sería redundante. Pero en C no puede determinar el tamaño de un elemento de matriz, debe especificar uno.
Considera esto:
int intArray[10];
fwrite(intArray, sizeof(int), 10, fd);
Si fwrite aceptó la cantidad de bytes, puede escribir lo siguiente:
int intArray[10];
fwrite(intArray, sizeof(int)*10, fd);
Pero es solo ineficiente. Tendrá sizeof (int) veces más llamadas al sistema.
Otro punto que debe tenerse en cuenta es que normalmente no desea que se escriba una parte de un elemento de matriz en un archivo. Quieres el entero entero o nada. fwrite devuelve una cantidad de elementos escritos con éxito. Entonces, si descubres que solo se escriben 2 bytes bajos de un elemento, ¿qué harías?
En algunos sistemas (debido a la alineación) no puede acceder a un byte de un entero sin crear una copia y desplazamiento.
Esto es pura especulación, sin embargo, en los últimos tiempos (algunos aún existen), muchos sistemas de archivos no eran flujos de bytes simples en un disco duro.
Muchos sistemas de archivos se basan en registros, por lo tanto, para satisfacer dichos sistemas de archivos de manera eficiente, deberá especificar el número de elementos ("registros"), permitiendo que fwrite / fread opere en el almacenamiento como registros, no solo como flujos de bytes.
La diferencia en fread (buf, 1000, 1, stream) y fread (buf, 1, 1000, stream) es que en el primer caso solo se obtiene un fragmento de 1000 bytes o nuthin, si el archivo es más pequeño y en el segundo caso, obtiene todo en el archivo a menos de y hasta 1000 bytes.
Probablemente se remonta a la forma en que se implementó la E / S de archivos. (De vuelta en el día) Podría haber sido más rápido escribir / leer archivos en bloques y luego escribir todo a la vez.
Se basa en cómo se implementa fread .
La única especificación UNIX dice
Para cada objeto, las llamadas de tamaño se realizarán a la función fgetc () y los resultados se almacenarán, en el orden leído, en una matriz de caracteres sin signo que se superpondrá exactamente al objeto.
fgetc también tiene esta nota:
Dado que fgetc () opera en bytes, leer un carácter que consta de múltiples bytes (o "un carácter de múltiples bytes") puede requerir múltiples llamadas a fgetc ().
Por supuesto, esto es anterior a las sofisticadas codificaciones de caracteres de bytes variables como UTF-8.
El SUS observa que esto en realidad se toma de los documentos ISO C.