[Powered by Google Translate] [Fil I / O]
[Jason Hirschhorn, Harvard University]
[Dette er CS50, CS50.TV]
Når vi tenker på en fil, kommer det til hjernen er et Microsoft Word-dokument,
et JPEG-bilde, eller en MP3-sang,
og vi samhandler med hver av disse typer filer på forskjellige måter.
For eksempel, i et Word-dokument legger vi tekst
mens med et JPEG-bilde kan vi beskjære kantene eller retusjere fargene.
Likevel under panseret alle filene i datamaskinen vår er ingenting mer
enn en lang sekvens av nuller og enere.
Det er opp til den spesifikke applikasjonen som samhandler med filen
å bestemme hvordan å behandle denne lange sekvensen og presentere det til brukeren.
På den ene siden, kan et dokument se på bare en byte,
eller 8 nuller og enere, og vise et ASCII-tegn på skjermen.
På den annen side kan et punktgrafikkbilde se på 3 byte,
eller 24 nuller og enere,
og tolke dem som 3 heksadesimale tall
som representerer verdiene for rød, grønn og blå
i én piksel i et bilde.
Uansett hva de kan se ut på skjermen, på sin kjernekompetanse,
filene er noe mer enn en sekvens av nuller og enere.
Så la oss dykke inn og se på hvordan vi faktisk manipulere disse nuller og enere
når det gjelder å skrive til og lese fra en fil.
>> Jeg vil starte med å bryte det ned i en enkel 3-stegs prosess.
Deretter vil jeg dykke inn i to kode eksempler som viser disse tre delene.
Til slutt vil jeg gå gjennom prosessen og noen av de viktigste detaljene.
Som med hvilken som helst fil som sitter på skrivebordet ditt,
den første tingen å gjøre er å åpne den.
I C gjør vi dette ved å erklære en peker til en forhåndsdefinert struct
som representerer en fil på disken.
I denne funksjonen samtale, vi også bestemme om vi ønsker å skrive til eller lese fra filen.
Deretter gjør vi selve lesing og skriving.
Det finnes en rekke spesialiserte funksjoner vi kan bruke i denne delen,
og nesten alle av dem starter med bokstaven F, som står for filen.
Sist, beslektet med den lille røde X i det øverste hjørnet av filene åpnes på datamaskinen,
vi lukke filen med en endelig funksjon samtale.
Nå som vi har en generell ide om hva vi skal gjøre,
la oss dykke inn koden.
>> I denne katalogen har vi to C-filer og tilhørende kjørbare filer.
Skrivemaskinen Programmet tar en kommandolinje argument,
navnet på dokumentet vi ønsker å skape.
I dette tilfellet vil vi kaller det doc.txt.
La oss kjøre programmet og skriv et par linjer.
Hei. Mitt navn er Jason.
Til slutt vil vi tast "quit".
Hvis vi nå liste opp alle filene i denne katalogen,
Vi ser at et nytt dokument eksisterer kalt doc.txt.
Det er filen dette programmet nettopp opprettet.
Og selvfølgelig er det for noe mer enn en lang sekvens av nuller og enere.
Hvis vi åpner denne nye filen,
vi ser de 3 linjer med kode vi inngått programmet vårt -
Hei. May heter Jason.
Men hva som faktisk skjer når typewriter.c kjører?
Den første linjen av interesse for oss er linje 24.
I denne linjen, erklærer vi vår filpekeren.
Funksjonen som returnerer denne pekeren, fopen, tar to argumenter.
Den første er filnavnet inkludert filtypen hvis hensiktsmessig.
Husker at en filtype ikke påvirker filen på sitt laveste nivå.
Vi er alltid å gjøre med en lang sekvens av nuller og enere.
Men det gjør påvirker hvordan filene tolkes og hvilke applikasjoner som brukes til å åpne dem.
Det andre argumentet til fopen er en enkelt bokstav
som står for det vi har tenkt å gjøre etter at vi åpner filen.
Det er tre alternativer for dette argumentet - W, R og A.
Vi har valgt w i dette tilfellet fordi vi ønsker å skrive til filen.
R, som du kan sikkert gjette, er for lesing til filen.
Og en er for føye til filen.
Mens både W og en kan brukes for å skrive til filer,
w vil begynne å skrive fra begynnelsen av filen
og potensielt overskrive alle data som tidligere har blitt lagret.
Som standard filen vi åpner, hvis det ikke allerede finnes,
er skapt i vår nåværende arbeidskatalog.
Men hvis vi ønsker å få tilgang til eller opprette en fil på et annet sted,
i det første argumentet for fopen,
Vi kan angi en filbane i tillegg til filnavnet.
Mens den første delen av denne prosessen er bare en kodelinje lang,
det er alltid god praksis å inkludere et annet sett av linjer
som kontrollerer at filen var vellykket åpnet eller opprettet.
Hvis fopen returnerer null, ville vi ikke ønsker å gå videre med vårt program,
og dette kan skje hvis operativsystemet er ute av minne
eller hvis vi prøver å åpne en fil i en katalog som vi ikke har de riktige tillatelsene.
>> Del to av prosessen foregår i skrivemaskinenes mens loop.
Vi bruker en CS50 bibliotek-funksjonen for å få innspill fra brukeren,
og forutsatt at de ikke ønsker å avslutte programmet,
vi bruker funksjonen fputs å ta strengen og skrive den til filen.
fputs er bare ett av de mange funksjonene vi kan bruke til å skrive til filen.
Andre inkluderer fwrite, fputc, og selv fprintf.
Uavhengig av den bestemte funksjon ender vi opp med å bruke, selv om,
alle av dem trenger å vite, via sine argumenter,
minst to ting -
hva som må skrives og hvor det er behov for å bli skrevet til.
I vårt tilfelle, er input strengen som må skrives
og fp er pekeren som leder oss til der vi skriver.
I dette programmet, er del to av prosessen ganske grei.
Vi er rett og slett å ta en streng fra brukeren
og legge det direkte til file vår med lite til ingen validering av inndata eller sikkerhetskontroller.
Ofte vil imidlertid del to ta opp mesteparten av koden.
Endelig er del tre på linje 58, der vi lukke filen.
Her kaller vi fclose og gi det vår opprinnelige filen pekeren.
I den påfølgende linjen, går vi tilbake null, signaliserte slutten av programmet vårt.
Og, ja, er del tre så enkelt som det.
>> La oss gå videre til å lese fra filer.
Tilbake i katalogen vår har vi en fil som heter printer.c.
La oss kjøre det med filen vi nettopp opprettet -
doc.txt.
Dette programmet, som navnet antyder, vil bare skrive ut innholdet i filen sendes til den.
Og der har vi det.
Linjene med kode vi hadde skrevet tidligere og lagret i doc.txt.
Hei. Mitt navn er Jason.
Hvis vi dykke inn printer.c,
vi ser at mye av koden ligner det vi bare gikk gjennom i typewriter.c.
Faktisk linje 22, der vi åpnet filen,
og 39 linjer, der vi lukket filen,
er begge nesten identisk med typewriter.c, lagre for fopen andre argumentet.
Denne gangen vi leser fra en fil,
så vi har valgt r istedenfor w.
Således, la oss fokusere på den andre delen av prosessen.
I linje 35, som den andre tilstand i våre 4 løkke,
vi gjør et kall til fgets,
følgesvenn funksjonen til fputs fra før.
Denne gangen har vi tre argumenter.
Den første er pekeren til rekken av tegn der strengen skal lagres.
Den andre er det maksimale antall tegn som skal leses.
Og den tredje er pekeren til filen som vi jobber.
Du vil merke at for loop slutter når fgets returnerer null.
Det er to grunnen til at dette kan ha skjedd.
Først, kan en feil har oppstått.
Sekund, og mer sannsynlig, slutten av filen nådd og ingen flere tegn ble lest.
I tilfelle du lurer, finnes to funksjoner gjør at tillate oss å fortelle
som grunn er årsaken til denne spesielle nullpeker.
Og, ikke overraskende, siden de har å gjøre med å jobbe med filer,
både fError funksjonen og feof funksjonen start med bokstaven f.
>> Til slutt, før vi konkluderer, en rask kommentar om slutten av filen funksjon,
som, som nevnt tidligere, er skrevet som feof.
Ofte vil du finne deg selv ved hjelp stund og etter looper å gradvis lese deg gjennom filer.
Dermed trenger du en måte å avslutte disse loopene når du kommer til slutten av disse filene.
Ringe feof på filpekeren og sjekke for å se om det er sant
ville gjøre nettopp det.
Dermed kan en stund loop med tilstanden (! Feof (fp)) virke som en helt riktig løsning.
Men si at vi har én linje igjen i vår tekstfil.
Vi vil delta i vår mens loop og alt vil fungere som planlagt.
På neste runde gjennom, vil vårt program for å se om feof av fp er sant,
men - og dette er det avgjørende punktet å forstå her -
det vil ikke være sant ennå.
Det er fordi den hensikt feof er ikke å kontrollere
hvis neste samtale til et Lesefunksjonen vil treffe enden av filen,
men heller å sjekke hvorvidt slutten av filen er allerede nådd.
I tilfelle av dette eksemplet,
leser den siste linjen av filen vår går helt knirkefritt,
men programmet ennå ikke vet at vi har truffet slutten av filen vår.
Det er ikke før det gjør en ekstra lest at det motvirker slutten av filen.
Dermed vil en korrekt tilstand være følgende:
fgets og sine tre argumenter - utgang, størrelsen på produksjonen, og fp -
og alle som ikke lik null.
Dette er den tilnærmingen vi tok i printer.c,
og i dette tilfellet, etter løkken kommer ut,
du kan kalle feof eller fError å informere brukeren om den spesifikke begrunnelsen for spennende denne sløyfen.
>> Skriving til og lesing fra en fil er, på sitt mest grunnleggende,
en enkel 3-stegs prosess.
Først åpner vi filen.
Sekund, setter vi noen ting inn i filen vår, eller ta noen ting ut av det.
Tredje, lukker vi filen.
Første og siste deler er lette.
Den midtre delen er der det vanskelige ting ligger.
Og selv om under panseret vi alltid arbeider med en lang sekvens av nuller og enere,
det hjelper når koding for å legge et lag av abstraksjon
som gjør sekvensen til noe som mer ligner det vi er vant til å se.
For eksempel, hvis vi jobber med en 24-bit bitmap fil,
Vi vil sannsynligvis være å lese eller skrive tre byte om gangen.
I så fall ville det være fornuftig å definere og hensiktsmessig navn
en struct som er 3 byte stor.
>> Selv arbeider med filer kan virke komplisert,
utnytte dem tillater oss å gjøre noe virkelig bemerkelsesverdig.
Vi kan endre tilstanden i verden utenfor vårt program,
vi kan skape noe som lever utover liv i vårt program,
eller vi kan selv endre noe som ble opprettet før vårt program startet.
Samhandle med filene er en virkelig kraftig del av programmering i C.
og jeg gleder meg til å se hva du kommer til å lage med det i koden som kommer.
Mitt navn er Jason Hirschhorn. Dette er CS50.
[CS50.TV]
>> [Latter]
Okay. Man ta. Here we go.
Når vi tenker på en fil - >> Å, vent. Unnskyld.
[Latter] Okay.
Hei der.
Når vi tenker på en fil -
Når du tenker på en fil - Ok. Fortell meg når du er klar.
Flott.
Selv leser fra en sufflør kan virke - ingen. Min feil.