[Powered by Google Translate] [File I / O]
[Jason Hirschhorn, Harvard University]
[Detta är CS50, CS50.TV]
När vi tänker på en fil, vad kommer att tänka på är ett Microsoft Word-dokument,
en JPEG-bild eller en MP3-låt,
och vi interagerar med var och en av dessa typer av filer på olika sätt.
Till exempel i ett Word-dokument som vi lägger till text
medan en JPEG-bild kan vi skära bort kanterna eller retuschera färger.
Men under huven alla filer i vår dator är inget annat
än en lång sekvens av nollor och ettor.
Det är upp till de specifika program som interagerar med filen
att besluta om hur att behandla denna långa sekvens och presentera det för användaren.
Å ena sidan kan ett dokument titta på endast en byte,
eller 8 nollor och ettor och visa ett ASCII-tecken på skärmen.
Å andra sidan kan en bitmappsbild titta på tre bitgrupper,
eller 24 nollor och ettor,
och tolka dem som 3 hexadecimala tal
som representerar värdena för röd, grön och blå
i en pixel av en bild.
Vad de kan se ut på skärmen, i sin kärna,
filer är inget annat än en sekvens av nollor och ettor.
Så låt oss dyka in och titta på hur vi faktiskt manipulera dessa nollor och ettor
när det gäller att skriva till och läsa från en fil.
>> Jag ska börja med att bryta ner det i en enkel 3-delad process.
Nu ska jag dyka in två kodexempel som visar dessa tre delar.
Slutligen kommer jag granska processen och några av dess viktigaste uppgifter.
Som med alla filer som sitter på skrivbordet,
det första du ska göra är att öppna den.
I C vi gör detta genom att deklarera en pekare till en fördefinierad struktur
som representerar en fil på hårddisken.
I denna funktion samtalet bestämmer vi också om vi vill skriva till eller läsa från filen.
Därefter gör vi själva läsning och skrivning.
Det finns ett antal specialiserade funktioner vi kan använda i denna del,
och nästan alla av dem börjar med bokstaven F, som står för fil.
Senast, besläktad med de små röda X i det övre hörnet av filerna öppnas på din dator,
Vi stänger filen med en slutlig funktionsanrop.
Nu när vi har en allmän uppfattning om vad vi ska göra,
låt oss dyka in koden.
>> I denna katalog har vi två C-filer och deras motsvarande körbara filer.
Skrivmaskinen programmet tar ett argument kommandoraden,
namnet på det dokument som vi vill skapa.
I det här fallet kommer vi kallar det doc.txt.
Låt oss köra programmet och ange ett par rader.
Hej. Mitt namn är Jason.
Slutligen kommer vi att skriva "quit".
Om vi ​​listar nu alla filer i den här katalogen,
ser vi att ett nytt dokument existerar kallas doc.txt.
Det är filen programmet nyss skapade.
Och naturligtvis, är det också ingenting mer än en lång sekvens av nollor och ettor.
Om vi ​​öppnar den nya filen,
Vi ser 3 rader kod vi in ​​i vårt program -
Hej. Maj namn är Jason.
Men vad är egentligen händer när typewriter.c körs?
Den första raden av intresse för oss är linje 24.
I denna linje, förklarar vi vår fil pekare.
Den funktion som returnerar denna pekare, fopen tar två argument.
Den första är filnamnet, inklusive filnamnstillägget vid behov.
Minns att ett filnamnstillägg inte påverkar filen på sin lägsta nivå.
Vi är alltid att göra med en lång sekvens av nollor och ettor.
Men det påverkar hur filer tolkas och vilka applikationer som används för att öppna dem.
Det andra argumentet till fopen är en enda bokstav
som står för vad vi planerar att göra efter att vi öppnar filen.
Det finns tre alternativ för detta argument - W, R och A.
Vi har valt w i detta fall eftersom vi vill skriva till filen.
R, som ni säkert kan gissa, är för att läsa till filen.
Och en är att lägga till filen.
Medan både v och en kan användas för att skriva till filer,
W kommer börja skriva från början av filen
och potentiellt skriva över data som tidigare har lagrats.
Som standard filen vi öppna, om det inte redan finns,
skapas i vår nuvarande arbetskatalog.
Men om vi vill komma åt eller skapa en fil på en annan plats,
i det första argumentet i fopen,
Vi kan ange en sökväg förutom filnamnet.
Medan den första delen av denna process är bara en kodrad lång,
det är alltid bra att inkludera en annan uppsättning linjer
som kontrollerar att filen framgångsrikt öppnat eller skapat.
Om fopen returnerar null, vill vi inte att gå vidare med vårt program,
och detta kan hända om operativsystemet är slut på minne
eller om vi försöker öppna en fil i en katalog som vi inte har rätt behörighet.
>> Del två i processen sker i skrivmaskin är while-slinga.
Vi använder en CS50 bibliotek funktion för att få input från användaren,
och förutsatt att de inte vill avsluta programmet,
Vi använder funktionen fputs att ta strängen och skriva till filen.
fputs är bara en av de många funktioner som vi kan använda för att skriva till filen.
Andra inkluderar fwrite, fputc och även fprintf.
Oavsett den särskilda funktion vi sluta använda, men
alla av dem behöver veta, via sina argument,
minst två saker -
vad som behöver skrivas och där den måste skrivas till.
I vårt fall, matas den sträng som behöver skrivas
och FP är pekaren som leder oss dit vi skriver.
I detta program ingår två i processen ganska enkelt.
Vi helt enkelt ta en sträng från användaren
och lägga den direkt till vår fil med lite till ingen indatavalidering eller säkerhetskontroller.
Men ofta kommer en del två tar upp den största delen av din kod.
Slutligen är del tre i rad 58, där vi stänger filen.
Här kallar vi fclose och ge det vårt ursprungliga filen pekare.
I den efterföljande raden återvänder vi noll, vilket signalerar slutet på vårt program.
Och, ja, en del tre så enkelt är det.
>> Låt oss gå vidare till att läsa från filer.
Tillbaka i vår katalog har vi en fil som heter printer.c.
Vi kör den med filen vi just skapat -
doc.txt.
Detta program, som namnet antyder, helt enkelt skriva ut innehållet i filen skickas till den.
Och där har vi det.
De kodrader vi hade skrivit tidigare och sparas i doc.txt.
Hej. Mitt namn är Jason.
Om vi ​​dyker in printer.c,
ser vi att mycket av koden liknar det vi bara gick igenom i typewriter.c.
Faktum linje 22, där vi öppnade filen,
och linje 39, där vi stängt filen,
är båda nästan identiskt med typewriter.c, med undantag för fopen andra argumentet.
Denna gång vi läser från en fil,
så vi har valt r istället för w.
Således, låt oss fokusera på den andra delen av processen.
I linje 35, som det andra villkoret i vår 4 slinga,
Vi ringer till fgets,
följeslagare funktionen fputs från förr.
Den här gången har vi tre argument.
Den första är pekaren till gruppen av tecken där strängen kommer att lagras.
Den andra är det maximala antalet tecken som ska läsas.
Och den tredje är pekaren till filen som vi jobbar.
Du kommer att märka att for-slingan avslutas när fgets returnerar null.
Det finns två skäl till att det kan ha hänt.
Först kan ett fel ha inträffat.
Andra, och mer troligt var slutet av filen nås och inga fler tecken lästes.
I fall du undrar, existerar två funktioner som gör att vi kan berätta
varför är orsaken till denna null pekare.
Och inte överraskande, eftersom de har att göra med att arbeta med filer,
både ferror funktionen och feof funktionen börjar med bokstaven f..
>> Slutligen, innan vi avslutar, en snabb anteckning om slutet av filen funktion,
vilket som just nämnts, skrivs som feof.
Ofta hittar du dig själv med hjälp tag och för slingor att successivt läsa dig igenom filer.
Därför behöver du ett sätt att avsluta dessa slingor när du når slutet av dessa filer.
Ringa feof på filen pekaren och kontrollera om det är sant
skulle göra just det.
Således kan en while-slinga med villkoret (! Feof (fp)) verka som en perfekt lämplig lösning.
Men säger att vi har en rad kvar i vår textfil.
Vi kommer in i vår while-slinga och allt kommer att fungera som planerat.
På nästa omgång igenom kommer vårt program att se om feof av fp är sant,
men - och detta är den avgörande punkten att förstå här -
det kommer inte vara sant ännu.
Det beror på att syftet med feof är inte att kontrollera
om nästa samtal till en läs funktion kommer att drabba slutet av filen,
utan snarare att kontrollera huruvida eller inte slutet av filen redan har nåtts.
I fallet med detta exempel,
läser den sista raden i vår fil går perfekt smidigt,
men programmet inte vet ännu att vi har drabbats slutet av vår fil.
Det är inte förrän den gör en ytterligare läst att det motverkar slutet av filen.
Sålunda skulle en korrekt tillstånd vara följande:
fgets och dess tre argument - utgång, storlek utgång, och FP -
och allt detta inte är lika med noll.
Detta är den strategi som vi tog i printer.c,
och i detta fall, efter avslutas slingan,
Du kan kalla feof eller ferror att informera användaren om den specifika resonemang för att lämna denna slinga.
>> Skriva till och läsa från en fil är i sin mest grundläggande,
en enkel 3-delad processen.
Först öppnar vi filen.
Andra sätter vi vissa saker i vår fil eller ta vissa saker av det.
Tredje, stänger vi ärendet.
Den första och sista delar är lätt.
Den mellersta delen är där knepiga grejer ligger.
Och även under huven vi alltid att göra med en lång sekvens av nollor och ettor,
det hjälper vid kodning att lägga ett lager av abstraktion
som förvandlar den sekvens till något som mer liknar vad vi är vana att se.
Till exempel, om vi arbetar med en 24-bitars bitmappsfil,
vi kommer sannolikt att läsa eller skriva tre byte åt gången.
I vilket fall skulle det vara meningsfullt att definiera och korrekt namn
en struktur som är 3 byte stor.
>> Även att arbeta med filer kan tyckas komplicerat,
utnyttja dem tillåter oss att göra något verkligen anmärkningsvärt.
Vi kan ändra tillståndet i världen utanför vårt program,
Vi kan skapa något som lever bortom livet i vårt program,
eller vi kan även ändra något som skapades före vårt program började springa.
Interagera med filer är en verkligt kraftfull del av programmering i C.
och jag är spännande att se vad du ska skapa med den i koden för att komma.
Mitt namn är Jason Hirschhorn. Detta är CS50.
[CS50.TV]
>> [Skratt]
Okej. Man ta. Nu kör vi.
När vi tänker på en fil - >> Åh, vänta. Ursäkta.
[Skratt] Okej.
Hej där.
När vi tänker på en fil -
När du tänker på en fil - Okej. Berätta när du är redo.
Åh, bra.
Även läsa från en teleprompter kan tyckas - nej. Min dåliga.