[Powered by Google Translate] [File I / O]
[Jason Hirschhorn, Harvard University]
[Dit is CS50, CS50.TV]
Als we denken aan een bestand, wat in je opkomt is een Microsoft Word-document,
een JPEG-afbeelding, of een MP3-song,
en we met elk van deze bestanden op verschillende manieren.
Bijvoorbeeld, in een Word-document dat we tekst toevoegen
terwijl met een JPEG-beeld dat we kunnen snijden de randen of retoucheren van de kleuren.
Maar onder de motorkap alle bestanden in onze computer zijn niets meer
dan een lange reeks van nullen en enen.
Het is aan de specifieke toepassing die samenwerkt met het bestand
om te beslissen hoe deze lange reeks te verwerken en te presenteren aan de gebruiker.
Enerzijds kan een document kijken slechts een byte,
of 8 nullen en enen, en tonen een ASCII-teken op het scherm.
Anderzijds kan een bitmapafbeelding kijken 3 bytes,
of 24 nullen en enen,
en interpreteren als 3 hexadecimale getallen
dat met de waarden voor rood, groen en blauw
in een pixel van het beeld.
Wat ze ook mogen lijken op uw scherm, in hun kern,
bestanden zijn niets meer dan een opeenvolging van nullen en enen.
Dus laten we duiken in en kijken hoe we eigenlijk manipuleren deze nullen en enen
als het gaat om schrijven en lezen uit een bestand.
>> Ik zal beginnen met het af te breken in een eenvoudig 3-delig proces.
Vervolgens zal ik een duik nemen in twee codevoorbeelden dat deze drie delen te tonen.
Tot slot zal ik beoordelen van het proces en een aantal van de meest belangrijke details.
Zoals bij elk bestand dat zit op je bureaublad,
het eerste ding om te doen is om te openen.
In C doen we dit door te verklaren een pointer naar een vooraf gedefinieerde struct
dat staat voor een bestand op de schijf.
In deze functie oproep ook beslissen of we willen schrijven naar of van het bestand te lezen.
Vervolgens hebben we het eigenlijke lezen en schrijven.
Er zijn een aantal gespecialiseerde functies die we kunnen gebruiken in dit deel,
en bijna alle van hen beginnen met de letter F, wat staat voor bestand.
Laatste, verwant aan de kleine rode X in de hoek van de bestanden te openen op uw computer,
sluiten we het bestand met een laatste aanroep.
Nu we een algemeen idee van wat we gaan doen,
laten we een duik in de code.
>> In deze map hebben we twee C-bestanden en de bijbehorende uitvoerbare bestanden.
De schrijfmachine programma duurt een command line argument,
de naam van het document dat we willen creëren.
In dit geval, wij noemen het doc.txt.
Laten we het programma uitvoeren en voer een paar regels.
Hi. Mijn naam is Jason.
Tot slot zullen we typen "te stoppen."
Als we nu een lijst van alle bestanden in deze map,
zien we dat een nieuw document bestaat genaamd doc.txt.
Dat is het bestand dit programma zojuist hebt gemaakt.
Natuurlijk is het ook niet meer dan een lange reeks van nullen en enen.
Als we openen dit nieuwe bestand,
zien we de 3 lijnen van code die we ingevoerd in ons programma -
Hi. May naam is Jason.
Maar wat er eigenlijk gebeurt wanneer typewriter.c loopt?
De eerste regel van belang voor ons is lijn 24.
In deze lijn, verklaren wij ons bestand pointer.
De functie die deze pointer, fopen terugkeert, neemt twee argumenten.
De eerste is de bestandsnaam inclusief de bestandsextensie indien van toepassing.
Bedenk dat een bestandsextensie niet het bestand op het laagste niveau te beïnvloeden.
We zijn altijd te maken met een lange reeks van nullen en enen.
Maar het doet invloed op hoe bestanden worden geïnterpreteerd en welke applicaties worden gebruikt om ze te openen.
Het tweede argument om fopen is een enkele letter
dat staat voor wat we van plan te doen na openen we het bestand.
Er zijn drie opties voor dit argument - W, R, en A.
We hebben gekozen w in dit geval want we willen om te schrijven naar het bestand.
R, zoals je waarschijnlijk wel kunt raden, is voor het lezen van het bestand.
En a is om naast het bestand.
Terwijl zowel w en kan worden gebruikt voor het schrijven naar bestanden,
w zal beginnen met het schrijven van het begin van het bestand
en mogelijk overschrijft alle gegevens die eerder zijn opgeslagen.
Standaard wordt het bestand openen we, als het nog niet bestaat,
wordt gemaakt in onze huidige werk-directory.
Echter, als we willen openen of een bestand op een andere locatie,
in het eerste argument van de fopen,
kunnen we u een map opgeeft, naast de bestandsnaam.
Terwijl het eerste deel van dit proces is slechts een regel code lang,
het is altijd een goede gewoonte om onder meer een andere set van regels
dat het inchecken om ervoor te zorgen dat het bestand met succes is geopend of gemaakt.
Als fopen null retourneert, zouden we niet willen om vooruit te smeden met ons programma,
en dit kan gebeuren als het besturingssysteem heeft onvoldoende geheugen beschikbaar
of als we proberen om een ​​bestand te openen in een directory waarvoor we niet over de juiste machtigingen beschikt.
>> Deel twee van het proces vindt plaats in terwijl typemachine lus.
We gebruiken een CS50 bibliotheekfunctie om invoer van de gebruiker,
en ervan uitgaande dat ze niet willen om het programma af te sluiten,
gebruiken we de functie fputs om de string te nemen en het naar het bestand te schrijven.
fputs is slechts een van de vele functies die we kunnen gebruiken om te schrijven naar het bestand.
Andere zijn fwrite, fputc, en zelfs fprintf.
Ongeacht de specifieke functie we uiteindelijk met behulp echter
allemaal moeten weten, via hun argumenten,
tenminste twee dingen -
wat er moet worden geschreven en waar het moet worden geschreven.
In ons geval ingang de string die moet worden geschreven
en fp is de wijzer die ons leidt naar de plek waar we aan het schrijven bent.
In dit programma, het tweede deel van het proces is vrij eenvoudig.
We gewoon het nemen van een string van de gebruiker
en toe te voegen direct naar onze bestand met weinig tot geen input validatie of veiligheidscontroles.
Vaak echter zal het tweede deel te nemen het grootste deel van je code.
Ten slotte gaat deel drie is op lijn 58, waar we het bestand sluiten.
Hier noemen we fclose en doorgeven onze oorspronkelijke bestands pointer.
In de daaropvolgende lijn, keren we terug nul, het signaleren van het einde van ons programma.
En ja, een deel drie is zo simpel als dat.
>> Laten we verder gaan met het lezen van bestanden.
Terug in onze directory hebben we een bestand met de naam printer.c.
Laten we het uit te voeren met het bestand dat we net gemaakt -
doc.txt.
Dit programma, zoals de naam suggereert, gewoon print de inhoud van het bestand doorgegeven aan.
En daar hebben we het.
De lijnen van code die we hadden eerder getypt en opgeslagen in doc.txt.
Hi. Mijn naam is Jason.
Als we een duik in printer.c,
zien we dat een groot deel van de code ziet er vergelijkbaar met wat we liepen gewoon door in typewriter.c.
Inderdaad lijn 22, waar we het bestand opende,
en lijn 39, waar we het dossier gesloten,
zijn beide bijna identiek aan typewriter.c, met uitzondering van fopen tweede argument.
Deze keer zijn we het lezen van een bestand,
dus we hebben gekozen voor r in plaats van w.
Zo, laten we focussen op het tweede deel van het proces.
In regel 35, de tweede voorwaarde in ons 4-lus,
maken we een oproep om fgets,
de metgezel functie om fputs van voor.
Deze keer hebben we drie argumenten.
De eerste is de aanwijzer naar de karakter array waar de string worden opgeslagen.
De tweede is het maximum aantal tekens worden gelezen.
En de derde is de pointer naar het bestand waarmee we werken.
U zult merken dat de for-lus eindigt wanneer fgets null retourneert.
Er zijn twee reden dat dit kan zijn gebeurd.
Ten eerste kan er een fout opgetreden.
Tweede en waarschijnlijker is het einde van het bestand bereikt en geen tekens zijn gelezen.
In het geval dat je je afvraagt, worden twee functies bestaan ​​die ons in staat stellen om te vertellen
die reden is de oorzaak voor deze specifieke null pointer.
En, niet verrassend, omdat ze te maken hebben met het werken met bestanden,
zowel de fError functie en de feof functie start met de letter f.
>> Tot slot, voordat we concluderen, een kort bericht over het einde van het bestand functie,
die, zoals zojuist vermeld, is geschreven als feof.
Vaak vind je jezelf met behulp van tijd en voor lussen om uw weg geleidelijk door te lezen bestanden.
Dus, heb je een manier nodig om deze lussen eindigt nadat u aan het einde van deze bestanden.
Bellen feof op uw bestands pointer en controleren om te zien of het waar is
zou dat te doen.
Zo zou een while-lus aan de voorwaarde (! Feof (fp)) lijken een perfect passende oplossing.
Maar zeggen dat we een lijn meer in onze tekst bestand.
We voeren onze while-lus en alles zal werken zoals gepland.
Op de volgende ronde door, zal ons programma om te zien of feof van fp waar is,
maar - en dit is het cruciale punt om hier te begrijpen -
het zal niet waar nog niet.
Dat komt omdat het doel van feof is niet te controleren
Als de volgende oproep naar een leesfunctie het einde van het bestand raken,
maar om te controleren of het einde van het bestand reeds is bereikt.
In het geval van dit voorbeeld,
het lezen van de laatste regel van ons bestand gaat perfect soepel,
maar het programma weet nog niet dat we het einde van ons bestand te raken.
Het is pas het doet een extra lezen dat het tellers aan het einde van het bestand.
Daarom zou een correcte toestand als volgt:
fgets en zijn drie argumenten - uitgang, de grootte van de output, en fp -
en al die niet gelijk aan nul.
Dit is de benadering die we in printer.c,
en in dit geval, na de loop uitgangen,
je zou kunnen noemen feof of fError om de gebruiker te informeren over de specifieke redenen voor het verlaten van deze lus.
>> Het schrijven en lezen van een bestand is, in zijn meest elementaire,
een eenvoudige 3-delig proces.
Ten eerste hebben we het bestand openen.
Ten tweede hebben we een aantal dingen in ons bestand of neem een ​​aantal dingen uit te halen.
Ten derde, sluiten we het bestand.
De eerste en laatste deel zijn eenvoudig.
Het middelste deel is de plaats waar de lastige dingen ligt.
En hoewel onder de motorkap zijn we altijd te maken met een lange reeks van nullen en enen,
het helpt bij het coderen van een laag van abstractie toe te voegen
dat verandert de volgorde in iets dat meer lijkt op wat we gewend zijn te zien.
Bijvoorbeeld, als we werken met een 24-bit bitmap-bestand,
zullen we waarschijnlijk het lezen of schrijven van drie bytes per keer.
In dat geval, zou het zinvol zijn om afdoende te kunnen definiëren en benoemen
een struct die 3 bytes groot.
>> Hoewel het werken met bestanden lijkt misschien ingewikkeld,
daarvan gebruik te maken stelt ons in staat om iets te doen echt opmerkelijk.
We kunnen de toestand van de wereld buiten ons programma,
we kunnen creëren iets dat leeft buiten het leven van ons programma,
of we kunnen zelfs veranderen iets dat is gemaakt voor het programma begon te rennen.
Interactie met bestanden is een echt krachtig onderdeel van de programmering in C.
en ik ben opgewonden om te zien wat je gaat om met haar te maken in de code te komen.
Mijn naam is Jason Hirschhorn. Dit is CS50.
[CS50.TV]
>> [Gelach]
Oke. Een te nemen. Daar gaan we.
Als we denken aan een bestand - >> Oh, wacht. Sorry.
[Gelach] Oke.
Hey there.
Als we denken aan een bestand -
Als je denkt aan een bestand - Oke. Vertel me als je klaar bent.
Oh, geweldig.
Hoewel het lezen van een autocue mag lijken - geen. Mijn fout.