[Powered by Google Translate] [File I / O]
[Jason Hirschhorn, Harvard University]
[Aquesta és CS50, CS50.TV]
Quan pensem en un arxiu, el que ve a la ment és un document de Microsoft Word,
una imatge JPEG, o una cançó MP3,
i ens relacionem amb cada un d'aquests tipus d'arxius de diferents maneres.
Per exemple, en un document de Word afegir el text
mentre que amb una imatge JPEG que podríem retallar les vores o retocar els colors.
No obstant això, sota el capó de tots els arxius en el nostre ordinador no són més
d'una llarga seqüència de zeros i uns.
Tot depèn de l'aplicació específica que interactua amb l'arxiu
per decidir com processar aquesta seqüència llarga i presentar-la al usuari.
D'una banda, un document pot mirar a un sol byte,
o 8 zeros i uns, i mostrar un caràcter ASCII a la pantalla.
D'altra banda, una imatge de mapa de bits pot mirar a 3 bytes,
o 24 zeros i uns,
i les interpreten com tres nombres hexadecimals
que representen els valors de vermell, verd i blau
en un píxel d'una imatge.
Diguin el que pot semblar a la pantalla, en el fons,
arxius no són res més que una seqüència de zeros i uns.
Així que anem a bussejar i veure com realment manipular aquests zeros i uns
quan es tracta de l'escriptura i lectura d'un arxiu.
>> Vaig a començar per el descomponen en un simple procés de 3 parts.
A continuació, vaig a bussejar en dos exemples de codi que mostren aquestes tres parts.
Finalment, vaig a revisar el procés i alguns dels seus detalls més importants.
Igual que amb qualsevol arxiu que seu al seu escriptori,
el primer que ha de fer és obrir-lo.
En C fem això en declarar un punter a una estructura predefinida
que representa un arxiu en el disc.
En aquesta crida de funció, també decidim si volem escriure o llegir des del fitxer.
A continuació, fem la lectura real i l'escriptura.
Hi ha una sèrie de funcions especialitzades que podem utilitzar en aquesta part,
i gairebé tots ells comencen amb la lletra F, que correspon a arxiu.
Finalment, semblant a la petita X vermella a l'extrem superior dels arxius oberts a l'equip,
tanquem l'arxiu amb una crida a la funció final.
Ara que tenim una idea general del que farem,
anem a bussejar en el codi.
>> En aquest directori, tenim dos arxius de C i els fitxers executables corresponents.
El programa de màquina d'escriure té un argument de línia d'ordres,
el nom del document que voleu crear.
En aquest cas, anem a dir-doc.txt.
Anem a executar el programa i entrar en un parell de línies.
Hi. El meu nom és Jason.
Finalment, escriurem "quit".
Si ara una llista de tots els arxius en aquest directori,
veiem que hi ha un nou document anomenat doc.txt.
Aquest és l'arxiu d'aquest programa acaba de crear.
I, per descomptat, també no és més que una llarga seqüència de zeros i uns.
Si obrim aquest nou arxiu,
veiem les 3 línies de codi que va entrar en el nostre programa -
Hi. Maig és el nom de Jason.
Però el que realment succeeix quan s'executa typewriter.c?
La primera línia d'interès per a nosaltres és la línia 24.
En aquesta línia, declarem el nostre punter d'arxiu.
La funció que retorna aquest indicador, fopen, pren dos arguments.
El primer és el nom de l'arxiu incloent l'extensió d'arxiu si és apropiat.
Recordem que una extensió d'arxiu no influeix en l'arxiu en el seu nivell més baix.
Sempre estem tractant amb una llarga seqüència de zeros i uns.
Però sí influeixen en com s'interpreten els arxius i les aplicacions que s'utilitzen per obrir-los.
El segon argument d'fopen és una sola lletra
que representa el que pensa fer després d'obrir l'arxiu.
Hi ha tres opcions per aquest argument - W, R i A.
Hem triat w en aquest cas perquè volem escriure a l'arxiu.
R, com vostè probablement pot endevinar, és per llegir l'arxiu.
I una és per annexar a la imatge.
Mentrestant w i una pot ser utilitzat per escriure en arxius,
w començarà a escriure des del principi de l'arxiu
i potencialment sobreescriure les dades que han estat prèviament emmagatzemats.
Per defecte, l'arxiu s'obrirà si no existeix ja,
es crea en el nostre directori de treball actual.
No obstant això, si volem iniciar sessió o crear un arxiu a un altre lloc,
en el primer argument de fopen,
és possible especificar una ruta d'arxiu en addició al nom de fitxer.
Mentre que la primera part d'aquest procés és només una línia de codi llarg,
que sempre és una bona pràctica incloure una altra sèrie de línies
El registre d'entrada per assegurar-se que l'arxiu s'ha obert correctament o creat.
Si fopen retorna un valor nul, no volem seguir endavant amb el nostre programa,
i això pot passar si el sistema operatiu no té memòria
o si intenta obrir un arxiu en un directori per al qual no comptava amb els permisos adequats.
>> La segona part del procés es realitza en bucle mentre que la màquina d'escriure.
Nosaltres fem servir una funció de biblioteca CS50 per obtenir entrada de l'usuari,
i assumint que no desitja sortir del programa,
fem servir els fputs funció per prendre la cadena i escriure-la al arxiu.
fputs és només una de les moltes funcions que podria utilitzar per escriure al fitxer.
Altres inclouen fwrite, fputc i fprintf fins i tot.
Independentment de la funció particular que acaben usant, però,
tots ells necessiten saber, a través dels seus arguments,
almenys dues coses -
el que ha de ser per escrit i en el qual s'ha d'escriure.
En el nostre cas, l'entrada és la cadena que necessita ser escrita
i fp és el punter que ens porta a on estem escrivint.
En aquest programa, la segona part del procés és bastant senzill.
Simplement estem prenent una cadena de l'usuari
i afegir directament al nostre arxiu amb poc o gens de validació d'entrada o controls de seguretat.
Sovint, però, la segona part s'ocuparà de la major part del seu codi.
Finalment, la tercera part està en la línia 58, on es tanca l'arxiu.
Aquí anomenem fclose i passar-ho nostre apuntador d'arxiu original.
En la línia següent, tornem a zero, el que indica el final del nostre programa.
I, sí, la tercera part és tan simple com això.
>> Anem a passar a la lectura dels arxius.
De tornada al nostre directori tenim un arxiu anomenat printer.c.
Anem a córrer amb l'arxiu que acabem de crear -
doc.txt.
Aquest programa, com el seu nom indica, simplement imprimir el contingut de l'arxiu se li ha passat.
I aquí el tenim.
Les línies de codi que havia escrit anteriorment i guardat en doc.txt.
Hi. El meu nom és Jason.
Si ens submergim en printer.c,
veiem que una gran part del codi és similar al que pots anar caminant a través de typewriter.c.
De fet la línia 22, on obrim l'arxiu,
i la línia 39, on es va tancar l'expedient,
són gairebé idèntics a typewriter.c, amb excepció d'argument fopen segon.
Aquesta vegada estem llegint d'un arxiu,
pel que hem triat en comptes de r w.
Per tant, ens centrarem en la segona part del procés.
En la línia 35, a la segona condició en nostre 4 loop,
fem una crida a fgets,
la funció fputs company d'abans.
En aquesta ocasió comptem amb tres arguments.
El primer és el punter a la matriu de caràcters en què s'emmagatzema la cadena.
El segon és el nombre màxim de caràcters a llegir.
I el tercer és el punter a l'arxiu amb el que estem treballant.
Es donarà compte de que el bucle acaba quan fgets retorna null.
Hi ha dues raons que això va poder haver succeït.
En primer lloc, un error pot haver passat.
En segon lloc, i més probablement, al final de l'arxiu es va aconseguir caràcters i no més llegir van ser.
En cas que vostè s'estigui preguntant, no hi ha dues funcions que ens permeten comptar
la qual cosa és la causa d'aquest punter nul en particular.
I, com és lògic, ja que tenen a veure amb treballar amb els arxius,
tant la funció ferror i la funció d'arrencada feof amb la lletra f.
>> Finalment, abans de concloure, una breu nota sobre el final de la funció d'arxiu,
que, com s'acaba d'esmentar, s'escriu com feof.
Sovint et trobaràs amb bucles while i for a llegir progressivament el seu camí a través dels arxius.
Per tant, vostè necessita una manera de posar fi a aquests bucles després d'arribar al final d'aquests arxius.
Trucar a feof al punter de l'arxiu i la comprovació per veure si és veritat
faria exactament això.
Per tant, un bucle mentre la condició (! Feof (fp)) pot semblar una solució perfectament adequada.
Però diguem que tenim una línia que queda al nostre arxiu de text.
Entrarem en el nostre bucle while i tot sortirà segons el planejat.
En la següent ronda a través del nostre programa comprovarà si feof de fp és cert,
però - i aquest és el punt crucial entendre aquí -
no serà veritat de moment.
Això és perquè el propòsit de feof no és comprovar
si la crida a una funció de lectura es prem el final de l'arxiu,
sinó més aviat per comprovar si o no el final de l'arxiu ja s'ha assolit.
En el cas d'aquest exemple,
la lectura de l'última línia del nostre fitxer va perfectament sense problemes,
però el programa encara no sap que hem arribat al final del nostre arxiu.
No és fins que ho faci una lectura addicional que contraresta el final de l'arxiu.
Així, una condició correcta seria la següent:
fgets i els seus tres arguments - de sortida, mida de sortida i FP -
i tot això no és igual a null.
Aquest és l'enfocament que adoptem en printer.c,
i en aquest cas, després de sortir del bucle,
vostè pot trucar o feof ferror per informar a l'usuari sobre el raonament específic per sortir d'aquest bucle.
>> Escriptura i lectura d'un arxiu és, en la seva forma més bàsica,
un simple procés de 3 parts.
En primer lloc, obrir el fitxer.
En segon lloc, hem posat algunes coses en el nostre arxiu o prendre algunes coses d'ella.
En tercer lloc, es tanca l'arxiu.
Les parts primera i última són fàcils.
La part central és on les coses es troba delicat.
I encara que per sota de la caputxa que sempre estem tractant amb una llarga seqüència de zeros i uns,
si ajuda al codificar per afegir una capa d'abstracció
que converteix la seqüència en alguna cosa que s'assembla més al que estem acostumats a veure.
Per exemple, si estem treballant amb un arxiu de mapa de bits de 24-bit,
que probablement va a llegir o escriure tres bytes alhora.
En aquest cas, tindria sentit per definir i nomenar apropiadament
una estructura que és de 3 bytes de grans dimensions.
>> Tot i treballar amb arxius pot semblar complicat,
la utilització d'ells ens permet fer alguna cosa veritablement notable.
Podem canviar l'estat del món fora del nostre programa,
podem crear alguna cosa que viu més enllà de la vida del nostre programa,
o fins i tot podem canviar alguna cosa que es va crear abans que el nostre programa va començar a córrer.
Interactuar amb els arxius és una part realment de gran abast de la programació en C.
i estic emocionat de veure el que crearem amb ella en el codi per venir.
El meu nom és Jason Hirschhorn. Això és CS50.
[CS50.TV]
>> [Rialles]
Bé. Una sola presa. Aquí anem.
Quan pensem en un arxiu - >> Oh, espera. Em sap greu.
[Rialles] Bé.
Hey there.
Quan pensem en un arxiu -
Quan vostè pensa en un arxiu - D'acord. Digues quan estiguis llest.
Oh, genial.
Encara que la lectura d'un teleprompter pot semblar - no. La meva malament.