[Powered by Google Translate] [File I / O]
[Jason Hirschhorn, Universitatea Harvard]
[Acest lucru este CS50, CS50.TV]
Când ne gândim la un fișier, ceea ce vine în minte este un document Microsoft Word,
o imagine JPEG, sau o melodie MP3,
și am interacționa cu fiecare dintre aceste tipuri de fișiere în moduri diferite.
De exemplu, într-un document Word se adauga text
în timp ce, cu o imagine JPEG am putea decupa margini sau retușa culorile.
Cu toate acestea, sub capota toate fișierele din computerul nostru nu sunt nimic mai mult
decât o secvență lungă de zero-uri și unu.
Este, până la aplicații specifice, care interacționează cu dosarul
să decidă cum să proceseze această secvență lungă și să îl prezinte utilizatorului.
Pe de o parte, un document poate te uiti la un singur octet,
sau 8 zerouri și cele, și afișează un caracter ASCII pe ecran.
Pe de altă parte, o imagine bitmap poate arata la 3 octeți,
sau 24 de zerouri și cele,
și le interpreteze ca 3 numere hexazecimale
care reprezintă valorile pentru roșu, verde și albastru
într-un pixel dintr-o imagine.
Indiferent care sunt acestea arata ca pe ecran, de la lor de bază,
Fișierele nu sunt nimic mai mult decât o secvență de zero-uri și cele.
Deci, haideți să se arunca cu capul în și uita-te la modul în care ne manipuleze, de fapt aceste zero și unu
atunci când vine vorba de scris și de citit dintr-un fișier.
>> Voi începe prin rupere-l în jos într-un simplu proces de 3-o parte.
În continuare, voi arunca cu capul în două exemple de cod care să demonstreze aceste trei părți.
În cele din urmă, voi revizui procesul, iar unele dintre detaliile sale cele mai importante.
Ca în orice fișier care se află pe desktop,
primul lucru de făcut este să-l deschidă.
În C vom face acest lucru prin a declara un pointer la o structura predefinit
care reprezintă un fișier de pe disc.
În acest apel de funcție, am, de asemenea, să decidem dacă vrem să scrie sau citi din fișierul.
În continuare, vom face citirea real și scris.
Există o serie de funcții de specialitate putem folosi în această parte,
și aproape toți dintre ei incep cu litera F, care vine de la dosar.
În sfârșit, asemănător cu X mici roșii în colțul de sus al fisierelor deschide pe computer,
am închide fișierul cu un apel de funcție finală.
Acum, că avem o idee generală despre ceea ce vom face,
Haideti sa patrundem in cod.
>> În acest director, avem două fișiere C și dosarele lor corespunzătoare executabile.
Programul de mașină de scris are un argument de linie de comandă,
denumirea documentului dorim să creăm.
În acest caz, vom numi doc.txt.
Să rula programul și introduceți un cuplu de linii.
Hi. Numele meu este Jason.
În cele din urmă, vom tastați "demisia".
Dacă am lista acum toate fișierele din acest director,
vom vedea că un nou document numit Exista doc.txt.
Asta e fișierul acest program tocmai creat.
Și, bineînțeles, prea este nimic mai mult decât o secvență lungă de zero-uri și unu.
Dacă vom deschide acest fișier nou,
vom vedea cele 3 linii de cod am intrat în programul nostru -
Hi. Numele mai este Jason.
Dar ce se întâmplă de fapt atunci când typewriter.c ruleaza?
Prima linie de interes pentru noi este linia 24.
În această linie, ne declarăm indicatorul nostru fișier.
Funcția care returnează acest pointer, fopen, ia două argumente.
Primul este numele fișierului, inclusiv extensia de fișier, dacă este cazul.
Amintiti-va ca o extensie de fișier nu influențează dosarului la nivelul cel mai scăzut.
Noi suntem întotdeauna de-a face cu o secvență lungă de zero-uri și unu.
Dar ea nu influențează modul în care fișierele sunt interpretate și aplicațiile care sunt utilizate pentru a le deschide.
Al doilea argument pentru a fopen este o singură literă
care stă pentru ceea ce avem de gând să facem după ce am deschis fișierul.
Există trei opțiuni pentru acest argument - W, R, și A.
Am ales g, în acest caz, pentru că vrem să scrie la dosar.
R, după cum puteți ghici, probabil, este pentru citirea la dosar.
Și o este pentru adăugarea la dosar.
În timp ce ambele w și o pot fi folosite pentru scrierea de la fișiere,
w va începe scrierea de la începutul fișierului
si suprascrie potențial orice date care au fost anterior stocate.
În mod implicit, fișierul ne deschide, în cazul în care nu există deja,
este creat în directorul nostru de muncă actual.
Cu toate acestea, în cazul în care dorim să acceseze sau să creați un fișier într-o locație diferită,
în primul argument al fopen,
am putea specifica o cale de fișier în plus față de numele fișierului.
În timp ce prima parte a acestui proces este doar o linie de cod lung,
este întotdeauna de bună practică pentru a include un alt set de linii
care să se asigure că dosarul a fost deschis cu succes sau create.
Dacă fopen returnează null, noi nu ar vrea să merge înainte cu programul nostru,
iar acest lucru se poate întâmpla în cazul în care sistemul de operare este în afara de memorie
sau în cazul în care vom încerca să deschideți un fișier într-un director pentru care noi nu avem permisiunile corespunzătoare.
>> Partea a doua a procesului de are loc în buclă în timp ce mașina de scris a lui.
Noi folosim o funcție de bibliotecă CS50 pentru a obține de intrare de la utilizator,
și presupunând că nu doresc să renunțe programul,
am folosit funcția fputs să ia șir și scrie-l la dosar.
fputs este doar unul dintre multe funcții le-ar putea folosi pentru a scrie la dosar.
Altele includ fwrite, fputc, și chiar fprintf.
Indiferent de anumite funcții vom ajunge folosind, însă,
toate acestea trebuie să știe, prin argumentele lor,
cel puțin două lucruri -
ceea ce trebuie să fie scrisă și în cazul în care acesta trebuie să fie scris.
În cazul nostru, de intrare este șirul care trebuie să fie scrise
și FP este indicatorul care ne îndrumă acolo unde suntem scris.
În acest program, partea a doua a procesului este destul de simplu.
Luăm doar un șir de utilizator
și adăugarea direct la dosarul nostru cu mic-la-nici o validare de intrare sau de controalele de securitate.
De multe ori, cu toate acestea, partea a doua va dura până cea mai mare parte a codului.
În cele din urmă, partea a treia, este pe linia 58, în cazul în care vom închide fișierul.
Aici ne numim fclose și trece-l pointerul nostru fișierul original.
În linia următoare, vom reveni la zero, de semnalizare sfârșitul programului nostru.
Și, da, partea a treia este la fel de simplu ca asta.
>> Să trecem la citirea din fișiere.
Înapoi în directorul nostru, avem un fișier numit printer.c.
Să-l rulați cu fișierul care tocmai am creat -
doc.txt.
Acest program, după cum sugerează și numele, va imprima pur și simplu conținutul fișierului a trecut să-l.
Și acolo îl avem.
Liniile de cod am tastat mai devreme și salvate în doc.txt.
Hi. Numele meu este Jason.
Dacă am arunca cu capul în printer.c,
vom vedea că o mulțime de cod arata similar cu ceea ce ne-am plimbat prin în typewriter.c.
Într-adevăr linia 22, în cazul în care am deschis fișierul,
și linia 39, în cazul în care am închis dosarul,
sunt ambele aproape identice cu typewriter.c, cu excepția argument fopen secunde.
De data aceasta suntem citirea dintr-un fișier,
de aceea am ales r în loc de w.
Astfel, să ne concentrăm asupra a doua parte a procesului.
În linia 35, astfel cum a doua condiție nostru de 4 buclă,
facem un apel la fgets,
funcția de însoțitor pentru fputs de dinainte.
De data aceasta avem trei argumente.
Primul este indicatorul la matrice de caractere în cazul în care șirul vor fi stocate.
Al doilea este numărul maxim de caractere care urmează să fie citite.
Iar al treilea este indicatorul la fișierul cu care lucram.
Veți observa că pentru bucla se termină atunci când fgets returnează null.
Există două motive care acest lucru ar putea să se fi întâmplat.
În primul rând, o eroare poate au avut loc.
În al doilea rând, și mai probabil, la sfârșitul dosarul a fost atins și personajele nu mai au fost citite.
În caz că vă întrebați, nu există două funcții, care ne permit să-i spun
care motiv este cauza pentru acest pointer nul special.
Și, nu în mod surprinzător, deoarece acestea au de a face cu lucrul cu fișiere,
atât funcția de ferror și începutul funcția feof cu litera F.
>> În cele din urmă, înainte de a ne încheia, o scurtă notă despre sfârșitul funcției fișier,
care, după cum am menționat, este scris ca feof.
De multe ori te vei găsi în timp ce utilizați și pentru bucle pentru a citi progresiv drum prin fișiere.
Astfel, veți avea nevoie de o modalitate de a pune capăt acestor bucle după ce ajunge la sfârșitul acestor fișiere.
Apelarea feof pe indicatorul fișierul și verificare pentru a vedea dacă e adevărat
ar face doar asta.
Astfel, o buclă în timp ce, cu conditia (feof (fp)!) S-ar putea părea o soluție perfect adecvată.
Cu toate acestea, spune ca avem o linie lăsat în fișier text noastră.
Vom intra în buclă în timp ce noastre si totul va merge conform planului.
La următoarea rundă, prin, programul nostru va verifica pentru a vedea dacă feof al FP este adevărat,
dar - și acest lucru este punctul crucial să înțelegem aici -
acesta nu va fi adevărat doar încă.
Asta pentru că scopul feof nu este de a verifica
în cazul în următorul apel la o funcție citi va lovi sfârșitul fișierului,
ci mai degrabă pentru a verifica dacă este sau nu la sfârșitul fișierului a fost deja atins.
În cazul acestui exemplu,
lectură ultima linie a fișierului de merge perfect fara probleme,
dar programul nu știe încă faptul că ne-am lovit la sfârșitul fișierului nostru.
Nu e până când se face o citire suplimentare pe care le contracarează sfârșitul fișierului.
Astfel, o condiție corectă ar fi următoarele:
fgets și cele trei argumente - ieșire, mărimea de ieșire, și FP -
și toate acestea nu este egal cu zero.
Aceasta este abordarea am luat în printer.c,
și, în acest caz, după ce iese din bucla,
ai putea apela feof sau ferror pentru a informa utilizatorul cu privire la motivarea specifică pentru ieșirea din această buclă.
>> Scrierea și citirea la dintr-un fișier este, în cea mai de bază,
un simplu proces de 3-o parte.
În primul rând, am deschideți fișierul.
În al doilea rând, am pus unele lucruri în fișierul nostru sau de a lua unele lucruri din ea.
În al treilea rând, am închide fișierul.
Piesele prima și ultima sunt ușor.
Partea de mijloc este în cazul în care lucrurile se află complicat.
Și, deși sub capota avem de-a face mereu cu o secvență lungă de zero-uri și unu,
aceasta nu ajută atunci când de codificare pentru a adăuga un strat de abstractizare
care transformă secvența în ceva care seamana foarte mult cu ceea ce suntem obișnuiți să vedem.
De exemplu, dacă lucrăm cu un fișier de tip bitmap de 24 de biți,
vom fi probabil la citirea sau scrierea trei octeți la un moment dat.
În acest caz, aceasta ar avea sens să definească și să numească în mod corespunzător
un struct care este de 3 octeți mare.
>> Deși lucrul cu fișiere poate părea complicat,
a le utiliza ne permite să facem ceva cu adevărat remarcabil.
Putem schimba starea lumii din afara programului nostru,
putem crea ceva care trăiește dincolo de viața al programului nostru,
sau putem schimba ceva chiar și care a fost creat înainte de programul nostru a început să ruleze.
Interacțiunea cu fișiere este o parte cu adevarat puternic de programare, în C.
și eu sunt încântat să văd ce ai de gând să creeze cu ea în codul pentru a veni.
Numele meu este Jason Hirschhorn. Acest lucru este CS50.
[CS50.TV]
>> [Râsete]
Bine. Un iau. Aici vom merge.
Când ne gândim la un fișier - >> Oh, stai. Scuze.
[Râsete] Ok.
Bună acolo.
Când ne gândim la un fișier -
Cand te gandesti la un fișier - Bine. Spune-mi când ești gata.
Oh, minunat.
Deși citirea de la un prompter poate parea - nr. Greșeala mea.