[Powered by Google Translate] [File I / O]
[Jason Hirschhorn, Harvard University]
[Esta es CS50, CS50.TV]
Cuando pensamos en un archivo, lo que viene a la mente es un documento de Microsoft Word,
una imagen JPEG, o una canción MP3,
y nos relacionamos con cada uno de estos tipos de archivos de diferentes maneras.
Por ejemplo, en un documento de Word que añadir el texto
mientras que con una imagen JPEG que podríamos recortar los bordes o retocar los colores.
Sin embargo, bajo el capó de todos los archivos en nuestro ordenador no son más
de una larga secuencia de ceros y unos.
Todo depende de la aplicación específica que interactúa con el archivo
para decidir cómo procesar esta secuencia larga y presentarla al usuario.
Por un lado, un documento puede parecer en un solo byte,
o 8 ceros y unos, y mostrar un carácter ASCII en la pantalla.
Por otra parte, una imagen de mapa de bits puede mirar a 3 bytes,
o 24 ceros y unos,
y las interpretan como tres números hexadecimales
que representan los valores de rojo, verde y azul
en un píxel de una imagen.
Digan lo que puede parecer en la pantalla, en el fondo,
archivos no son nada más que una secuencia de ceros y unos.
Así que vamos a bucear y ver cómo realmente manipular estos ceros y unos
cuando se trata de la escritura y lectura de un archivo.
>> Voy a empezar por lo descomponen en un simple proceso de 3 partes.
A continuación, voy a bucear en dos ejemplos de código que muestran estas tres partes.
Por último, voy a revisar el proceso y algunos de sus detalles más importantes.
Al igual que con cualquier archivo que se sienta en su escritorio,
lo primero que debe hacer es abrirlo.
En C hacemos esto al declarar un puntero a una estructura predefinida
que representa un archivo en el disco.
En esta llamada de función, también decidimos si queremos escribir o leer desde el archivo.
A continuación, hacemos la lectura real y la escritura.
Hay una serie de funciones especializadas que podemos utilizar en esta parte,
y casi todos ellos comienzan con la letra F, que corresponde a archivo.
Por último, semejante a la pequeña X roja en la esquina superior de los archivos abiertos en el equipo,
cerramos el archivo con una llamada a la función final.
Ahora que tenemos una idea general de lo que vamos a hacer,
vamos a bucear en el código.
>> En este directorio, tenemos dos archivos de C y sus archivos ejecutables correspondientes.
El programa de máquina de escribir tiene un argumento de línea de comandos,
el nombre del documento que desea crear.
En este caso, vamos a llamarlo doc.txt.
Vamos a ejecutar el programa y entrar en un par de líneas.
Hi. Mi nombre es Jason.
Por último, vamos a escribir "quit".
Si ahora una lista de todos los archivos en este directorio,
vemos que existe un nuevo documento llamado doc.txt.
Ese es el archivo de este programa acaba de crear.
Y, por supuesto, también no es más que una larga secuencia de ceros y unos.
Si abrimos este nuevo archivo,
vemos las 3 líneas de código que entró en nuestro programa -
Hi. Mayo es el nombre de Jason.
Pero lo que realmente sucede cuando se ejecuta typewriter.c?
La primera línea de interés para nosotros es la línea 24.
En esta línea, declaramos nuestro puntero de archivo.
La función que devuelve este indicador, fopen, toma dos argumentos.
El primero es el nombre del archivo incluyendo la extensión de archivo si es apropiado.
Recordemos que una extensión de archivo no influye en el archivo en su nivel más bajo.
Siempre estamos tratando con una larga secuencia de ceros y unos.
Pero sí influye la cantidad de archivos se interpretan y qué aplicaciones se utilizan para abrirlos.
El segundo argumento de fopen es una sola letra
que representa lo que piensa hacer después de abrir el archivo.
Hay tres opciones para este argumento - W, R y A.
Hemos elegido w en este caso porque queremos escribir en el archivo.
R, como usted probablemente puede adivinar, es para leer el archivo.
Y una es para anexar al archivo.
Mientras tanto w y una puede ser utilizado para escribir en archivos,
w comenzará a escribir desde el principio del archivo
y potencialmente sobrescribir los datos que han sido previamente almacenados.
De forma predeterminada, el archivo se abrirá si no existe ya,
se crea en nuestro directorio de trabajo actual.
Sin embargo, si queremos acceder o crear un archivo en una ubicación diferente,
en el primer argumento de fopen,
es posible especificar una ruta de archivo en adición al nombre de archivo.
Mientras que la primera parte de este proceso es sólo una línea de código largo,
que siempre es una buena práctica incluir otra serie de líneas
El registro de entrada para asegurarse de que el archivo se ha abierto correctamente o creado.
Si fopen devuelve un valor nulo, no queremos seguir adelante con nuestro programa,
y esto puede ocurrir si el sistema operativo no tiene memoria
o si intenta abrir un archivo en un directorio para el que no contaba con los permisos adecuados.
>> La segunda parte del proceso se realiza en bucle mientras que la máquina de escribir.
Nosotros usamos una función de biblioteca CS50 para obtener entrada del usuario,
y asumiendo que no desea salir del programa,
usamos los fputs función para tomar la cadena y escribirla en el archivo.
fputs es sólo una de las muchas funciones que podría utilizar para escribir en el archivo.
Otros incluyen fwrite, fputc y fprintf incluso.
Independientemente de la función particular que terminan usando, sin embargo,
todos ellos necesitan saber, a través de sus argumentos,
por lo menos dos cosas -
lo que tiene que ser por escrito y en el que hay que escribir.
En nuestro caso, la entrada es la cadena que necesita ser escrita
y fp es el puntero que nos lleva a donde estamos escribiendo.
En este programa, la segunda parte del proceso es bastante sencillo.
Simplemente estamos tomando una cadena del usuario
y añadir directamente a nuestro archivo con poca o ninguna validación de entrada o controles de seguridad.
A menudo, sin embargo, la segunda parte se ocupará de la mayor parte de su código.
Por último, la tercera parte está en la línea 58, donde se cierra el archivo.
Aquí llamamos fclose y pasarlo nuestro apuntador de archivo original.
En la línea siguiente, volvemos a cero, lo que indica el final de nuestro programa.
Y, sí, la tercera parte es tan simple como eso.
>> Vamos a pasar a la lectura de los archivos.
De vuelta en nuestro directorio tenemos un archivo llamado printer.c.
Vamos a correr con el archivo que acabamos de crear -
doc.txt.
Este programa, como su nombre indica, simplemente imprimir el contenido del archivo se le ha pasado.
Y ahí lo tenemos.
Las líneas de código que había escrito anteriormente y guardado en doc.txt.
Hi. Mi nombre es Jason.
Si nos sumergimos en printer.c,
vemos que una gran parte del código es similar a lo que puedes ir andando a través de typewriter.c.
De hecho la línea 22, donde abrimos el archivo,
y la línea 39, donde se cerró el expediente,
son casi idénticos a typewriter.c, con excepción de argumento fopen segundo.
Esta vez estamos leyendo de un archivo,
por lo que hemos elegido en lugar de r w.
Por lo tanto, vamos a centrarnos en la segunda parte del proceso.
En la línea 35, a la segunda condición en nuestro 4 loop,
hacemos un llamado a fgets,
la función fputs compañero de antes.
En esta ocasión contamos con tres argumentos.
El primero es el puntero a la matriz de caracteres en la que se almacena la cadena.
El segundo es el número máximo de caracteres a leer.
Y el tercero es el puntero al archivo con el que estamos trabajando.
Se dará cuenta de que el bucle termina cuando fgets devuelve null.
Hay dos razones que esto pudo haber sucedido.
En primer lugar, un error puede haber ocurrido.
En segundo lugar, y más probablemente, el final del archivo se alcanzó caracteres y no más leer fueron.
En caso de que usted se esté preguntando, no existen dos funciones que nos permiten contar
lo cual es la causa de este puntero nulo en particular.
Y, como es lógico, ya que tienen que ver con trabajar con los archivos,
tanto la función ferror y la función de arranque feof con la letra f.
>> Por último, antes de concluir, una breve nota sobre el final de la función de archivo,
que, como se acaba de mencionar, se escribe como feof.
A menudo te encontrarás con bucles while y for a leer progresivamente su camino a través de los archivos.
Por lo tanto, usted necesita una manera de poner fin a estos bucles después de llegar al final de estos archivos.
Llamar a feof en el puntero del archivo y la comprobación para ver si es verdad
haría exactamente eso.
Por lo tanto, un bucle mientras la condición (! Feof (fp)) puede parecer una solución perfectamente adecuada.
Sin embargo, digamos que tenemos una línea que queda en nuestro archivo de texto.
Vamos a entrar en nuestro bucle while y todo saldrá según lo planeado.
En la siguiente ronda a través de nuestro programa comprobará si feof de fp es cierto,
pero - y éste es el punto crucial entender aquí -
no va a ser verdad por el momento.
Eso es porque el propósito de feof no es comprobar
si la siguiente llamada a una función de lectura se pulsa el final del archivo,
sino más bien para comprobar si o no el final del archivo ya se ha alcanzado.
En el caso de este ejemplo,
la lectura de la última línea de nuestro fichero va perfectamente sin problemas,
pero el programa todavía no sabe que hemos alcanzado el final de nuestro archivo.
No es hasta que lo haga una lectura adicional que contrarresta el final del archivo.
Así, una condición correcta sería la siguiente:
fgets y sus tres argumentos - de salida, tamaño de la producción, y FP -
y todo eso no es igual a null.
Este es el enfoque que adoptamos en printer.c,
y en este caso, después de salir del bucle,
usted puede llamar o feof ferror para informar al usuario sobre el razonamiento específico para salir de este bucle.
>> Escritura y lectura de un archivo es, en su forma más básica,
un simple proceso de 3 partes.
En primer lugar, abrir el archivo.
En segundo lugar, hemos puesto algunas cosas en nuestro archivo o tomar algunas cosas de ella.
En tercer lugar, se cierra el archivo.
Las partes primera y última son fáciles.
La parte central es donde las cosas se encuentra delicado.
Y aunque por debajo de la capucha que siempre estamos tratando con una larga secuencia de ceros y unos,
sí ayuda al codificar para añadir una capa de abstracción
que convierte la secuencia en algo que se parece más a lo que estamos acostumbrados a ver.
Por ejemplo, si estamos trabajando con un archivo de mapa de bits de 24-bit,
que probablemente va a leer o escribir tres bytes a la vez.
En ese caso, tendría sentido para definir y nombrar apropiadamente
una estructura que es de 3 bytes de gran tamaño.
>> A pesar de trabajar con archivos puede parecer complicado,
la utilización de ellos nos permite hacer algo verdaderamente notable.
Podemos cambiar el estado del mundo fuera de nuestro programa,
podemos crear algo que vive más allá de la vida de nuestro programa,
o incluso podemos cambiar algo que se creó antes de que nuestro programa comenzó a correr.
Interactuar con los archivos es una parte realmente de gran alcance de la programación en C.
y estoy emocionado de ver lo que vamos a crear con ella en el código por venir.
Mi nombre es Jason Hirschhorn. Esto es CS50.
[CS50.TV]
>> [Risas]
Bien. Una sola toma. Aquí vamos.
Cuando pensamos en un archivo - >> Oh, espera. Lo siento.
[Risas] Bueno.
Hey there.
Cuando pensamos en un archivo -
Cuando usted piensa en un archivo - De acuerdo. Dime cuando estés listo.
Oh, genial.
Aunque la lectura de un teleprompter puede parecer - no. Mi mal.