1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [File I / O] 2 00:00:02,000 --> 00:00:04,000 [Jason Hirschhorn, Harvard University] 3 00:00:04,000 --> 00:00:07,000 [Dit is CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 Als we denken aan een bestand, wat in je opkomt is een Microsoft Word-document, 5 00:00:11,000 --> 00:00:14,000 een JPEG-afbeelding, of een MP3-song, 6 00:00:14,000 --> 00:00:17,000 en we met elk van deze bestanden op verschillende manieren. 7 00:00:17,000 --> 00:00:20,000 Bijvoorbeeld, in een Word-document dat we tekst toevoegen 8 00:00:20,000 --> 00:00:24,000 terwijl met een JPEG-beeld dat we kunnen snijden de randen of retoucheren van de kleuren. 9 00:00:24,000 --> 00:00:28,000 Maar onder de motorkap alle bestanden in onze computer zijn niets meer 10 00:00:28,000 --> 00:00:31,000 dan een lange reeks van nullen en enen. 11 00:00:31,000 --> 00:00:33,000 Het is aan de specifieke toepassing die samenwerkt met het bestand 12 00:00:33,000 --> 00:00:38,000 om te beslissen hoe deze lange reeks te verwerken en te presenteren aan de gebruiker. 13 00:00:38,000 --> 00:00:41,000 Enerzijds kan een document kijken slechts een byte, 14 00:00:41,000 --> 00:00:45,000 of 8 nullen en enen, en tonen een ASCII-teken op het scherm. 15 00:00:45,000 --> 00:00:48,000 Anderzijds kan een bitmapafbeelding kijken 3 bytes, 16 00:00:48,000 --> 00:00:50,000 of 24 nullen en enen, 17 00:00:50,000 --> 00:00:53,000 en interpreteren als 3 hexadecimale getallen 18 00:00:53,000 --> 00:00:56,000 dat met de waarden voor rood, groen en blauw 19 00:00:56,000 --> 00:00:58,000 in een pixel van het beeld. 20 00:00:58,000 --> 00:01:01,000 Wat ze ook mogen lijken op uw scherm, in hun kern, 21 00:01:01,000 --> 00:01:05,000 bestanden zijn niets meer dan een opeenvolging van nullen en enen. 22 00:01:05,000 --> 00:01:08,000 Dus laten we duiken in en kijken hoe we eigenlijk manipuleren deze nullen en enen 23 00:01:08,000 --> 00:01:12,000 als het gaat om schrijven en lezen uit een bestand. 24 00:01:12,000 --> 00:01:15,000 >> Ik zal beginnen met het af te breken in een eenvoudig 3-delig proces. 25 00:01:15,000 --> 00:01:19,000 Vervolgens zal ik een duik nemen in twee codevoorbeelden dat deze drie delen te tonen. 26 00:01:19,000 --> 00:01:23,000 Tot slot zal ik beoordelen van het proces en een aantal van de meest belangrijke details. 27 00:01:23,000 --> 00:01:25,000 Zoals bij elk bestand dat zit op je bureaublad, 28 00:01:25,000 --> 00:01:28,000 het eerste ding om te doen is om te openen. 29 00:01:28,000 --> 00:01:31,000 In C doen we dit door te verklaren een pointer naar een vooraf gedefinieerde struct 30 00:01:31,000 --> 00:01:33,000 dat staat voor een bestand op de schijf. 31 00:01:33,000 --> 00:01:38,460 In deze functie oproep ook beslissen of we willen schrijven naar of van het bestand te lezen. 32 00:01:38,460 --> 00:01:41,660 Vervolgens hebben we het eigenlijke lezen en schrijven. 33 00:01:41,660 --> 00:01:44,800 Er zijn een aantal gespecialiseerde functies die we kunnen gebruiken in dit deel, 34 00:01:44,800 --> 00:01:48,790 en bijna alle van hen beginnen met de letter F, wat staat voor bestand. 35 00:01:48,790 --> 00:01:53,560 Laatste, verwant aan de kleine rode X in de hoek van de bestanden te openen op uw computer, 36 00:01:53,560 --> 00:01:56,680 sluiten we het bestand met een laatste aanroep. 37 00:01:56,680 --> 00:01:59,540 Nu we een algemeen idee van wat we gaan doen, 38 00:01:59,540 --> 00:02:02,000 laten we een duik in de code. 39 00:02:02,000 --> 00:02:06,100 >> In deze map hebben we twee C-bestanden en de bijbehorende uitvoerbare bestanden. 40 00:02:06,100 --> 00:02:09,710 De schrijfmachine programma duurt een command line argument, 41 00:02:09,710 --> 00:02:12,060 de naam van het document dat we willen creëren. 42 00:02:12,060 --> 00:02:16,160 In dit geval, wij noemen het doc.txt. 43 00:02:16,160 --> 00:02:19,080 Laten we het programma uitvoeren en voer een paar regels. 44 00:02:19,080 --> 00:02:23,660 Hi. Mijn naam is Jason. 45 00:02:23,660 --> 00:02:26,710 Tot slot zullen we typen "te stoppen." 46 00:02:26,710 --> 00:02:29,720 Als we nu een lijst van alle bestanden in deze map, 47 00:02:29,720 --> 00:02:33,770 zien we dat een nieuw document bestaat genaamd doc.txt. 48 00:02:34,190 --> 00:02:36,110 Dat is het bestand dit programma zojuist hebt gemaakt. 49 00:02:36,110 --> 00:02:40,520 Natuurlijk is het ook niet meer dan een lange reeks van nullen en enen. 50 00:02:41,100 --> 00:02:43,260 Als we openen dit nieuwe bestand, 51 00:02:43,260 --> 00:02:45,870 zien we de 3 lijnen van code die we ingevoerd in ons programma - 52 00:02:46,060 --> 00:02:49,060 Hi. May naam is Jason. 53 00:02:49,580 --> 00:02:52,090 Maar wat er eigenlijk gebeurt wanneer typewriter.c loopt? 54 00:02:52,810 --> 00:02:55,520 De eerste regel van belang voor ons is lijn 24. 55 00:02:55,560 --> 00:02:58,490 In deze lijn, verklaren wij ons bestand pointer. 56 00:02:59,080 --> 00:03:03,140 De functie die deze pointer, fopen terugkeert, neemt twee argumenten. 57 00:03:03,140 --> 00:03:07,440 De eerste is de bestandsnaam inclusief de bestandsextensie indien van toepassing. 58 00:03:07,440 --> 00:03:10,980 Bedenk dat een bestandsextensie niet het bestand op het laagste niveau te beïnvloeden. 59 00:03:10,980 --> 00:03:14,640 We zijn altijd te maken met een lange reeks van nullen en enen. 60 00:03:14,640 --> 00:03:19,630 Maar het doet invloed op hoe bestanden worden geïnterpreteerd en welke applicaties worden gebruikt om ze te openen. 61 00:03:19,630 --> 00:03:22,290 Het tweede argument om fopen is een enkele letter 62 00:03:22,290 --> 00:03:25,300 dat staat voor wat we van plan te doen na openen we het bestand. 63 00:03:25,300 --> 00:03:30,630 Er zijn drie opties voor dit argument - W, R, en A. 64 00:03:30,630 --> 00:03:34,900 We hebben gekozen w in dit geval want we willen om te schrijven naar het bestand. 65 00:03:34,900 --> 00:03:38,820 R, zoals je waarschijnlijk wel kunt raden, is voor het lezen van het bestand. 66 00:03:38,820 --> 00:03:41,760 En a is om naast het bestand. 67 00:03:41,760 --> 00:03:44,960 Terwijl zowel w en kan worden gebruikt voor het schrijven naar bestanden, 68 00:03:44,960 --> 00:03:47,460 w zal beginnen met het schrijven van het begin van het bestand 69 00:03:47,460 --> 00:03:50,810 en mogelijk overschrijft alle gegevens die eerder zijn opgeslagen. 70 00:03:50,810 --> 00:03:54,070 Standaard wordt het bestand openen we, als het nog niet bestaat, 71 00:03:54,070 --> 00:03:57,180 wordt gemaakt in onze huidige werk-directory. 72 00:03:57,180 --> 00:04:00,540 Echter, als we willen openen of een bestand op een andere locatie, 73 00:04:00,540 --> 00:04:02,650 in het eerste argument van de fopen, 74 00:04:02,650 --> 00:04:05,840 kunnen we u een map opgeeft, naast de bestandsnaam. 75 00:04:05,840 --> 00:04:09,490 Terwijl het eerste deel van dit proces is slechts een regel code lang, 76 00:04:09,490 --> 00:04:12,350 het is altijd een goede gewoonte om onder meer een andere set van regels 77 00:04:12,350 --> 00:04:15,930 dat het inchecken om ervoor te zorgen dat het bestand met succes is geopend of gemaakt. 78 00:04:15,930 --> 00:04:20,300 Als fopen null retourneert, zouden we niet willen om vooruit te smeden met ons programma, 79 00:04:20,300 --> 00:04:23,270 en dit kan gebeuren als het besturingssysteem heeft onvoldoende geheugen beschikbaar 80 00:04:23,270 --> 00:04:27,940 of als we proberen om een ​​bestand te openen in een directory waarvoor we niet over de juiste machtigingen beschikt. 81 00:04:27,940 --> 00:04:31,780 >> Deel twee van het proces vindt plaats in terwijl typemachine lus. 82 00:04:31,780 --> 00:04:35,000 We gebruiken een CS50 bibliotheekfunctie om invoer van de gebruiker, 83 00:04:35,000 --> 00:04:37,190 en ervan uitgaande dat ze niet willen om het programma af te sluiten, 84 00:04:37,190 --> 00:04:41,940 gebruiken we de functie fputs om de string te nemen en het naar het bestand te schrijven. 85 00:04:41,940 --> 00:04:46,700 fputs is slechts een van de vele functies die we kunnen gebruiken om te schrijven naar het bestand. 86 00:04:46,700 --> 00:04:51,920 Andere zijn fwrite, fputc, en zelfs fprintf. 87 00:04:51,920 --> 00:04:54,840 Ongeacht de specifieke functie we uiteindelijk met behulp echter 88 00:04:54,840 --> 00:04:57,480 allemaal moeten weten, via hun argumenten, 89 00:04:57,480 --> 00:04:59,670 tenminste twee dingen - 90 00:04:59,670 --> 00:05:03,140 wat er moet worden geschreven en waar het moet worden geschreven. 91 00:05:03,140 --> 00:05:07,240 In ons geval ingang de string die moet worden geschreven 92 00:05:07,240 --> 00:05:11,290 en fp is de wijzer die ons leidt naar de plek waar we aan het schrijven bent. 93 00:05:11,290 --> 00:05:15,330 In dit programma, het tweede deel van het proces is vrij eenvoudig. 94 00:05:15,330 --> 00:05:17,360 We gewoon het nemen van een string van de gebruiker 95 00:05:17,360 --> 00:05:22,120 en toe te voegen direct naar onze bestand met weinig tot geen input validatie of veiligheidscontroles. 96 00:05:22,120 --> 00:05:26,160 Vaak echter zal het tweede deel te nemen het grootste deel van je code. 97 00:05:26,160 --> 00:05:30,580 Ten slotte gaat deel drie is op lijn 58, waar we het bestand sluiten. 98 00:05:30,580 --> 00:05:34,860 Hier noemen we fclose en doorgeven onze oorspronkelijke bestands pointer. 99 00:05:34,860 --> 00:05:39,500 In de daaropvolgende lijn, keren we terug nul, het signaleren van het einde van ons programma. 100 00:05:39,500 --> 00:05:42,630 En ja, een deel drie is zo simpel als dat. 101 00:05:42,630 --> 00:05:45,260 >> Laten we verder gaan met het lezen van bestanden. 102 00:05:45,260 --> 00:05:48,220 Terug in onze directory hebben we een bestand met de naam printer.c. 103 00:05:48,220 --> 00:05:50,910 Laten we het uit te voeren met het bestand dat we net gemaakt - 104 00:05:50,910 --> 00:05:53,350 doc.txt. 105 00:05:53,350 --> 00:05:58,150 Dit programma, zoals de naam suggereert, gewoon print de inhoud van het bestand doorgegeven aan. 106 00:05:58,150 --> 00:06:00,230 En daar hebben we het. 107 00:06:00,230 --> 00:06:03,780 De lijnen van code die we hadden eerder getypt en opgeslagen in doc.txt. 108 00:06:03,780 --> 00:06:06,980 Hi. Mijn naam is Jason. 109 00:06:06,980 --> 00:06:09,120 Als we een duik in printer.c, 110 00:06:09,120 --> 00:06:13,570 zien we dat een groot deel van de code ziet er vergelijkbaar met wat we liepen gewoon door in typewriter.c. 111 00:06:13,570 --> 00:06:16,720 Inderdaad lijn 22, waar we het bestand opende, 112 00:06:16,720 --> 00:06:19,220 en lijn 39, waar we het dossier gesloten, 113 00:06:19,220 --> 00:06:23,890 zijn beide bijna identiek aan typewriter.c, met uitzondering van fopen tweede argument. 114 00:06:23,890 --> 00:06:26,510 Deze keer zijn we het lezen van een bestand, 115 00:06:26,510 --> 00:06:29,040 dus we hebben gekozen voor r in plaats van w. 116 00:06:29,040 --> 00:06:31,950 Zo, laten we focussen op het tweede deel van het proces. 117 00:06:31,950 --> 00:06:36,060 In regel 35, de tweede voorwaarde in ons 4-lus, 118 00:06:36,060 --> 00:06:38,590 maken we een oproep om fgets, 119 00:06:38,590 --> 00:06:42,190 de metgezel functie om fputs van voor. 120 00:06:42,190 --> 00:06:44,660 Deze keer hebben we drie argumenten. 121 00:06:44,660 --> 00:06:48,810 De eerste is de aanwijzer naar de karakter array waar de string worden opgeslagen. 122 00:06:48,810 --> 00:06:52,670 De tweede is het maximum aantal tekens worden gelezen. 123 00:06:52,670 --> 00:06:56,010 En de derde is de pointer naar het bestand waarmee we werken. 124 00:06:56,010 --> 00:07:00,780 U zult merken dat de for-lus eindigt wanneer fgets null retourneert. 125 00:07:00,780 --> 00:07:02,940 Er zijn twee reden dat dit kan zijn gebeurd. 126 00:07:02,940 --> 00:07:05,380 Ten eerste kan er een fout opgetreden. 127 00:07:05,380 --> 00:07:10,740 Tweede en waarschijnlijker is het einde van het bestand bereikt en geen tekens zijn gelezen. 128 00:07:10,740 --> 00:07:14,040 In het geval dat je je afvraagt, worden twee functies bestaan ​​die ons in staat stellen om te vertellen 129 00:07:14,040 --> 00:07:17,160 die reden is de oorzaak voor deze specifieke null pointer. 130 00:07:17,160 --> 00:07:21,090 En, niet verrassend, omdat ze te maken hebben met het werken met bestanden, 131 00:07:21,090 --> 00:07:26,940 zowel de fError functie en de feof functie start met de letter f. 132 00:07:26,940 --> 00:07:32,130 >> Tot slot, voordat we concluderen, een kort bericht over het einde van het bestand functie, 133 00:07:32,130 --> 00:07:36,690 die, zoals zojuist vermeld, is geschreven als feof. 134 00:07:36,690 --> 00:07:41,550 Vaak vind je jezelf met behulp van tijd en voor lussen om uw weg geleidelijk door te lezen bestanden. 135 00:07:41,550 --> 00:07:45,790 Dus, heb je een manier nodig om deze lussen eindigt nadat u aan het einde van deze bestanden. 136 00:07:45,790 --> 00:07:50,510 Bellen feof op uw bestands pointer en controleren om te zien of het waar is 137 00:07:50,510 --> 00:07:52,310 zou dat te doen. 138 00:07:52,310 --> 00:07:59,820 Zo zou een while-lus aan de voorwaarde (! Feof (fp)) lijken een perfect passende oplossing. 139 00:07:59,820 --> 00:08:03,770 Maar zeggen dat we een lijn meer in onze tekst bestand. 140 00:08:03,770 --> 00:08:07,130 We voeren onze while-lus en alles zal werken zoals gepland. 141 00:08:07,130 --> 00:08:12,750 Op de volgende ronde door, zal ons programma om te zien of feof van fp waar is, 142 00:08:12,750 --> 00:08:15,430 maar - en dit is het cruciale punt om hier te begrijpen - 143 00:08:15,430 --> 00:08:17,770 het zal niet waar nog niet. 144 00:08:17,770 --> 00:08:21,110 Dat komt omdat het doel van feof is niet te controleren 145 00:08:21,110 --> 00:08:24,400 Als de volgende oproep naar een leesfunctie het einde van het bestand raken, 146 00:08:24,400 --> 00:08:28,190 maar om te controleren of het einde van het bestand reeds is bereikt. 147 00:08:28,190 --> 00:08:30,140 In het geval van dit voorbeeld, 148 00:08:30,140 --> 00:08:32,780 het lezen van de laatste regel van ons bestand gaat perfect soepel, 149 00:08:32,780 --> 00:08:36,210 maar het programma weet nog niet dat we het einde van ons bestand te raken. 150 00:08:36,210 --> 00:08:40,549 Het is pas het doet een extra lezen dat het tellers aan het einde van het bestand. 151 00:08:40,549 --> 00:08:43,210 Daarom zou een correcte toestand als volgt: 152 00:08:43,210 --> 00:08:49,330 fgets en zijn drie argumenten - uitgang, de grootte van de output, en fp - 153 00:08:49,330 --> 00:08:52,570 en al die niet gelijk aan nul. 154 00:08:52,570 --> 00:08:55,260 Dit is de benadering die we in printer.c, 155 00:08:55,260 --> 00:08:57,890 en in dit geval, na de loop uitgangen, 156 00:08:57,890 --> 00:09:04,290 je zou kunnen noemen feof of fError om de gebruiker te informeren over de specifieke redenen voor het verlaten van deze lus. 157 00:09:04,290 --> 00:09:08,100 >> Het schrijven en lezen van een bestand is, in zijn meest elementaire, 158 00:09:08,100 --> 00:09:10,150 een eenvoudige 3-delig proces. 159 00:09:10,150 --> 00:09:12,530 Ten eerste hebben we het bestand openen. 160 00:09:12,530 --> 00:09:16,740 Ten tweede hebben we een aantal dingen in ons bestand of neem een ​​aantal dingen uit te halen. 161 00:09:16,740 --> 00:09:19,200 Ten derde, sluiten we het bestand. 162 00:09:19,200 --> 00:09:21,170 De eerste en laatste deel zijn eenvoudig. 163 00:09:21,170 --> 00:09:23,920 Het middelste deel is de plaats waar de lastige dingen ligt. 164 00:09:23,920 --> 00:09:27,760 En hoewel onder de motorkap zijn we altijd te maken met een lange reeks van nullen en enen, 165 00:09:27,760 --> 00:09:30,710 het helpt bij het coderen van een laag van abstractie toe te voegen 166 00:09:30,710 --> 00:09:35,350 dat verandert de volgorde in iets dat meer lijkt op wat we gewend zijn te zien. 167 00:09:35,350 --> 00:09:39,570 Bijvoorbeeld, als we werken met een 24-bit bitmap-bestand, 168 00:09:39,570 --> 00:09:43,290 zullen we waarschijnlijk het lezen of schrijven van drie bytes per keer. 169 00:09:43,290 --> 00:09:46,450 In dat geval, zou het zinvol zijn om afdoende te kunnen definiëren en benoemen 170 00:09:46,450 --> 00:09:48,980 een struct die 3 bytes groot. 171 00:09:48,980 --> 00:09:51,410 >> Hoewel het werken met bestanden lijkt misschien ingewikkeld, 172 00:09:51,410 --> 00:09:54,530 daarvan gebruik te maken stelt ons in staat om iets te doen echt opmerkelijk. 173 00:09:54,530 --> 00:09:58,880 We kunnen de toestand van de wereld buiten ons programma, 174 00:09:58,880 --> 00:10:01,730 we kunnen creëren iets dat leeft buiten het leven van ons programma, 175 00:10:01,730 --> 00:10:07,190 of we kunnen zelfs veranderen iets dat is gemaakt voor het programma begon te rennen. 176 00:10:07,190 --> 00:10:11,210 Interactie met bestanden is een echt krachtig onderdeel van de programmering in C. 177 00:10:11,210 --> 00:10:15,300 en ik ben opgewonden om te zien wat je gaat om met haar te maken in de code te komen. 178 00:10:15,300 --> 00:10:19,770 Mijn naam is Jason Hirschhorn. Dit is CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [Gelach] 181 00:10:25,940 --> 00:10:29,330 Oke. Een te nemen. Daar gaan we. 182 00:10:49,000 --> 00:10:52,140 Als we denken aan een bestand - >> Oh, wacht. Sorry. 183 00:10:52,140 --> 00:10:56,800 [Gelach] Oke. 184 00:11:06,620 --> 00:11:09,970 Hey there. 185 00:11:13,670 --> 00:11:16,310 Als we denken aan een bestand - 186 00:11:17,610 --> 00:11:20,710 Als je denkt aan een bestand - Oke. Vertel me als je klaar bent. 187 00:11:20,710 --> 00:11:22,520 Oh, geweldig. 188 00:11:22,520 --> 00:11:26,180 Hoewel het lezen van een autocue mag lijken - geen. Mijn fout.