1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [Fil I / O] 2 00:00:02,000 --> 00:00:04,000 [Jason Hirschhorn, Harvard University] 3 00:00:04,000 --> 00:00:07,000 [Dette er CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 Når vi tænker på en fil, hvad der kommer til at tænke på er en Microsoft Word-dokument, 5 00:00:11,000 --> 00:00:14,000 et JPEG-billede, eller en MP3-sang, 6 00:00:14,000 --> 00:00:17,000 og vi interagerer med hver af disse typer af filer på forskellige måder. 7 00:00:17,000 --> 00:00:20,000 For eksempel har vi i et Word-dokument tilføje tekst 8 00:00:20,000 --> 00:00:24,000 mens med et JPEG-billede, vi muligvis beskære de kanter eller retoucheres farver. 9 00:00:24,000 --> 00:00:28,000 Men under kølerhjelmen alle filer i vores computer er intet mere 10 00:00:28,000 --> 00:00:31,000 end en lang sekvens af nuller og ettaller. 11 00:00:31,000 --> 00:00:33,000 Det er op til den specifikke applikation, der interagerer med filen 12 00:00:33,000 --> 00:00:38,000 at beslutte, hvordan at behandle denne lange sekvens og præsentere det for brugeren. 13 00:00:38,000 --> 00:00:41,000 På den ene side kan et dokument se på én byte, 14 00:00:41,000 --> 00:00:45,000 eller 8 nuller og ettaller, og vise et ASCII-tegn på skærmen. 15 00:00:45,000 --> 00:00:48,000 På den anden side kan en bitmapbillede se på 3 byte, 16 00:00:48,000 --> 00:00:50,000 eller 24 nuller og ettaller, 17 00:00:50,000 --> 00:00:53,000 og fortolke dem som 3 hexadecimale tal 18 00:00:53,000 --> 00:00:56,000 der repræsenterer værdier for rød, grøn og blå 19 00:00:56,000 --> 00:00:58,000 i en pixel i et billede. 20 00:00:58,000 --> 00:01:01,000 Uanset hvad de kan se ud på din skærm, på deres kernekompetencer, 21 00:01:01,000 --> 00:01:05,000 filer er intet mere end en sekvens af nuller og ettaller. 22 00:01:05,000 --> 00:01:08,000 Så lad os dykke ned og se på, hvordan vi rent faktisk manipulere disse nuller og ettaller 23 00:01:08,000 --> 00:01:12,000 når det kommer til at skrive til og læse fra en fil. 24 00:01:12,000 --> 00:01:15,000 >> Jeg vil starte med at bryde det ned i en simpel 3-delt proces. 25 00:01:15,000 --> 00:01:19,000 Dernæst vil jeg dykke i to kodeeksempler, der viser disse tre dele. 26 00:01:19,000 --> 00:01:23,000 Endelig vil jeg gennemgå processen og nogle af de mest vigtige detaljer. 27 00:01:23,000 --> 00:01:25,000 Som med enhver fil, der sidder på skrivebordet, 28 00:01:25,000 --> 00:01:28,000 den første ting at gøre, er at åbne den. 29 00:01:28,000 --> 00:01:31,000 I C gør vi dette ved at erklære en pointer til en foruddefineret struct 30 00:01:31,000 --> 00:01:33,000 der repræsenterer en fil på disken. 31 00:01:33,000 --> 00:01:38,460 I denne funktion opkald, også vi beslutter, om vi vil skrive til eller læse fra filen. 32 00:01:38,460 --> 00:01:41,660 Næste, vi gøre det faktiske læsning og skrivning. 33 00:01:41,660 --> 00:01:44,800 Der er en række specialiserede funktioner, vi kan bruge i denne del, 34 00:01:44,800 --> 00:01:48,790 og næsten alle af dem starter med bogstavet F, som står for fil. 35 00:01:48,790 --> 00:01:53,560 Sidst, beslægtet med de små røde X i øverste hjørne af filerne åbner på din computer, 36 00:01:53,560 --> 00:01:56,680 vi lukker filen med en endelig funktion opkald. 37 00:01:56,680 --> 00:01:59,540 Nu hvor vi har en generel idé om, hvad vi vil gøre, 38 00:01:59,540 --> 00:02:02,000 Lad os dykke ned i koden. 39 00:02:02,000 --> 00:02:06,100 >> I denne mappe har vi to C-filer og deres tilsvarende eksekverbare filer. 40 00:02:06,100 --> 00:02:09,710 Skrivemaskinen program tager et kommandolinje argument, 41 00:02:09,710 --> 00:02:12,060 navnet på det dokument, som vi ønsker at skabe. 42 00:02:12,060 --> 00:02:16,160 I dette tilfælde vil vi kalde det doc.txt. 43 00:02:16,160 --> 00:02:19,080 Lad os køre programmet og indtaste et par linjer. 44 00:02:19,080 --> 00:02:23,660 Hi. Mit navn er Jason. 45 00:02:23,660 --> 00:02:26,710 Endelig vil vi skrive "quit". 46 00:02:26,710 --> 00:02:29,720 Hvis vi nu en liste over alle de filer i denne mappe, 47 00:02:29,720 --> 00:02:33,770 vi se, at et nyt dokument eksisterer kaldet doc.txt. 48 00:02:34,190 --> 00:02:36,110 Det er den fil, dette program netop har oprettet. 49 00:02:36,110 --> 00:02:40,520 Og selvfølgelig er det også er intet mere end en lang sekvens af nuller og ettaller. 50 00:02:41,100 --> 00:02:43,260 Hvis vi åbner denne nye fil, 51 00:02:43,260 --> 00:02:45,870 ser vi de 3 linjer kode vi trådte ind i vores program - 52 00:02:46,060 --> 00:02:49,060 Hi. Maj navn er Jason. 53 00:02:49,580 --> 00:02:52,090 Men hvad der rent faktisk foregår, når typewriter.c kører? 54 00:02:52,810 --> 00:02:55,520 Den første linje af interesse for os er linje 24. 55 00:02:55,560 --> 00:02:58,490 I denne linje, erklærer vi vores fil pointer. 56 00:02:59,080 --> 00:03:03,140 Den funktion, der returnerer denne pointer, fopen tager to argumenter. 57 00:03:03,140 --> 00:03:07,440 Den første er filnavnet, herunder filtypen om nødvendigt. 58 00:03:07,440 --> 00:03:10,980 Husk på, at en fil forlængelse ikke påvirker filen på sit laveste niveau. 59 00:03:10,980 --> 00:03:14,640 Vi er altid at gøre med en lang sekvens af nuller og ettaller. 60 00:03:14,640 --> 00:03:19,630 Men det gør indflydelse hvordan filer fortolkes og hvilke programmer der bruges til at åbne dem. 61 00:03:19,630 --> 00:03:22,290 Det andet argument for fopen er et enkelt bogstav 62 00:03:22,290 --> 00:03:25,300 der står for hvad vi planlægger at gøre efter vi åbner filen. 63 00:03:25,300 --> 00:03:30,630 Der er tre muligheder for dette argument - W, R og A. 64 00:03:30,630 --> 00:03:34,900 Vi har valgt w i dette tilfælde, fordi vi ønsker at skrive til filen. 65 00:03:34,900 --> 00:03:38,820 R, som du nok kan gætte, er til læsning af filen. 66 00:03:38,820 --> 00:03:41,760 Og a er for tilføjelse af filen. 67 00:03:41,760 --> 00:03:44,960 Mens både w og en kan anvendes til at skrive til filer, 68 00:03:44,960 --> 00:03:47,460 w vil begynde at skrive fra begyndelsen af ​​filen 69 00:03:47,460 --> 00:03:50,810 og potentielt overskrive data, der tidligere er blevet gemt. 70 00:03:50,810 --> 00:03:54,070 Som standard, den fil, vi åbner, hvis den ikke allerede findes 71 00:03:54,070 --> 00:03:57,180 er skabt i vores nuværende arbejdsmappe. 72 00:03:57,180 --> 00:04:00,540 Men hvis vi ønsker at få adgang til eller oprette en fil i en anden placering, 73 00:04:00,540 --> 00:04:02,650 i det første argument for fopen, 74 00:04:02,650 --> 00:04:05,840 Vi kan angive en filsti i tillæg til filnavnet. 75 00:04:05,840 --> 00:04:09,490 Mens den første del af denne proces er kun én linje kode lange, 76 00:04:09,490 --> 00:04:12,350 det er altid god praksis at inkludere et andet sæt linjer 77 00:04:12,350 --> 00:04:15,930 at kontrollere, at sikre, at filen med held blev åbnet eller oprettet. 78 00:04:15,930 --> 00:04:20,300 Hvis fopen returnerer null, ville vi ikke ønsker at gå videre med vores program, 79 00:04:20,300 --> 00:04:23,270 og dette kan ske, hvis operativsystemet er løbet tør for hukommelse 80 00:04:23,270 --> 00:04:27,940 eller hvis vi forsøger at åbne en fil i en mappe, som vi ikke har de rette tilladelser. 81 00:04:27,940 --> 00:04:31,780 >> Anden del af processen finder sted i skrivemaskine s medens løkken. 82 00:04:31,780 --> 00:04:35,000 Vi anvender en CS50 biblioteksfunktion at få input fra brugeren, 83 00:04:35,000 --> 00:04:37,190 og under forudsætning af, at de ikke ønsker at forlade programmet, 84 00:04:37,190 --> 00:04:41,940 vi bruger funktionen fputs at tage snoren og skrive det til filen. 85 00:04:41,940 --> 00:04:46,700 fputs er kun én af de mange funktioner, vi kunne bruge til at skrive til filen. 86 00:04:46,700 --> 00:04:51,920 Andre omfatter fwrite, fputc, og selv fprintf. 87 00:04:51,920 --> 00:04:54,840 Uanset den særlige funktion, vi ender med at bruge, selv om, 88 00:04:54,840 --> 00:04:57,480 alle af dem har brug for at vide, via deres argumenter, 89 00:04:57,480 --> 00:04:59,670 mindst to ting - 90 00:04:59,670 --> 00:05:03,140 hvad der skal skrives, og hvor den skal skrives til. 91 00:05:03,140 --> 00:05:07,240 I vores tilfælde er input den streng, der skal skrives 92 00:05:07,240 --> 00:05:11,290 og fp er markøren, der leder os til, hvor vi er ved at skrive. 93 00:05:11,290 --> 00:05:15,330 I dette program, er anden del af processen temmelig ligetil. 94 00:05:15,330 --> 00:05:17,360 Vi blot at tage en snor fra brugeren 95 00:05:17,360 --> 00:05:22,120 og tilføje det direkte til vores fil med lille-til-ingen validering af input eller sikkerhedskontrol. 96 00:05:22,120 --> 00:05:26,160 Men ofte vil anden del tage op størstedelen af ​​din kode. 97 00:05:26,160 --> 00:05:30,580 Endelig behandler del tre er på linie 58, hvor vi lukker filen. 98 00:05:30,580 --> 00:05:34,860 Her kalder vi fclose og videregive det vores oprindelige fil pointer. 99 00:05:34,860 --> 00:05:39,500 I den efterfølgende linie, vender vi nul, signalerer afslutningen på vores program. 100 00:05:39,500 --> 00:05:42,630 Og ja, del tre er så simpelt er det. 101 00:05:42,630 --> 00:05:45,260 >> Lad os gå videre til læsning fra filer. 102 00:05:45,260 --> 00:05:48,220 Tilbage i vores bibliotek har vi en fil kaldet printer.c. 103 00:05:48,220 --> 00:05:50,910 Lad os køre det med den fil, vi lige har oprettet - 104 00:05:50,910 --> 00:05:53,350 doc.txt. 105 00:05:53,350 --> 00:05:58,150 Dette program, som navnet antyder, vil blot udskrive indholdet af filen blev leveret til. 106 00:05:58,150 --> 00:06:00,230 Og der har vi det. 107 00:06:00,230 --> 00:06:03,780 De linjer kode, vi havde skrevet tidligere og gemmes i doc.txt. 108 00:06:03,780 --> 00:06:06,980 Hi. Mit navn er Jason. 109 00:06:06,980 --> 00:06:09,120 Hvis vi dykker ned i printer.c, 110 00:06:09,120 --> 00:06:13,570 vi se, at en masse af koden ligner det, vi bare gik igennem i typewriter.c. 111 00:06:13,570 --> 00:06:16,720 Faktisk linie 22, hvor vi åbnede filen, 112 00:06:16,720 --> 00:06:19,220 og linie 39, hvor vi lukkede filen, 113 00:06:19,220 --> 00:06:23,890 er begge næsten identisk med typewriter.c, bortset fopen andet argument. 114 00:06:23,890 --> 00:06:26,510 Denne gang vi læser fra en fil, 115 00:06:26,510 --> 00:06:29,040 så vi har valgt ri stedet for w. 116 00:06:29,040 --> 00:06:31,950 Således lad os fokusere på den anden del af processen. 117 00:06:31,950 --> 00:06:36,060 På linje 35, som den anden betingelse i vores 4 loop 118 00:06:36,060 --> 00:06:38,590 vi foretage et opkald til fgets, 119 00:06:38,590 --> 00:06:42,190 følgesvend funktionen til fputs fra før. 120 00:06:42,190 --> 00:06:44,660 Denne gang har vi tre argumenter. 121 00:06:44,660 --> 00:06:48,810 Den første er markøren til de mange figurer, hvor strengen skal lagres. 122 00:06:48,810 --> 00:06:52,670 Det andet er den maksimale antal tegn, der skal læses. 123 00:06:52,670 --> 00:06:56,010 Og den tredje er markøren til den fil, som vi arbejder. 124 00:06:56,010 --> 00:07:00,780 Du vil opdage, at for-løkken slutter, når fgets returnerer null. 125 00:07:00,780 --> 00:07:02,940 Der er to grund, at dette kan være sket. 126 00:07:02,940 --> 00:07:05,380 Først kan være sket en fejl. 127 00:07:05,380 --> 00:07:10,740 Sekund, og mere sandsynligt, blev slutningen af ​​filen nået, og ikke flere tegn blev aflæst. 128 00:07:10,740 --> 00:07:14,040 Hvis du undrer dig over, har to funktioner findes, der giver os mulighed for at fortælle 129 00:07:14,040 --> 00:07:17,160 hvorfor er årsagen til denne særlige null pointer. 130 00:07:17,160 --> 00:07:21,090 Og ikke overraskende, da de har at gøre med at arbejde med filer, 131 00:07:21,090 --> 00:07:26,940 både den ferror funktionen og feof funktionen start med bogstavet f. 132 00:07:26,940 --> 00:07:32,130 >> Endelig, før vi slutter, en hurtig bemærkning omkring slutningen af ​​fil-funktionen, 133 00:07:32,130 --> 00:07:36,690 der, som lige nævnt, er skrevet som feof. 134 00:07:36,690 --> 00:07:41,550 Ofte vil du finde dig selv ved hjælp af tid og for-løkker til gradvis læse din vej gennem filer. 135 00:07:41,550 --> 00:07:45,790 Derfor skal du have en måde at afslutte disse sløjfer, når du når til slutningen af ​​disse filer. 136 00:07:45,790 --> 00:07:50,510 Opkald feof på din fil pointer og kontrol for at se, om det er sandt 137 00:07:50,510 --> 00:07:52,310 ville gøre netop det. 138 00:07:52,310 --> 00:07:59,820 Således kan en while-løkke med betingelse (! Feof (fp)) synes som en perfekt passende løsning. 139 00:07:59,820 --> 00:08:03,770 Men siger vi har en linje tilbage i vores tekst-fil. 140 00:08:03,770 --> 00:08:07,130 Vi vil deltage i vores while-løkke og alt vil arbejde som planlagt. 141 00:08:07,130 --> 00:08:12,750 På næste runde igennem, vil vores program tjekke om feof af fp er sandt, 142 00:08:12,750 --> 00:08:15,430 men - og det er det afgørende punkt for at forstå her - 143 00:08:15,430 --> 00:08:17,770 vil det ikke være rigtigt endnu. 144 00:08:17,770 --> 00:08:21,110 Det er fordi formålet med feof ikke er at kontrollere 145 00:08:21,110 --> 00:08:24,400 hvis den næste opkald til en aflæsningsfunktion vil ramme i slutningen af ​​filen, 146 00:08:24,400 --> 00:08:28,190 men at kontrollere, om slutningen af ​​filen er allerede nået. 147 00:08:28,190 --> 00:08:30,140 I forbindelse med dette eksempel, 148 00:08:30,140 --> 00:08:32,780 læst den sidste linje i vores fil går perfekt glat, 149 00:08:32,780 --> 00:08:36,210 men programmet endnu ikke ved, at vi har ramt slutningen af ​​vores fil. 150 00:08:36,210 --> 00:08:40,549 Det er ikke indtil det gør en ekstra læst, at det modvirker slutningen af ​​filen. 151 00:08:40,549 --> 00:08:43,210 Således vil en korrekt tilstand, er følgende: 152 00:08:43,210 --> 00:08:49,330 fgets og dets tre argumenter - output, størrelse af produktion og FP - 153 00:08:49,330 --> 00:08:52,570 og alt dette ikke lig med nul. 154 00:08:52,570 --> 00:08:55,260 Det er den tilgang, vi tog i printer.c, 155 00:08:55,260 --> 00:08:57,890 og i dette tilfælde, efter løkken udgange 156 00:08:57,890 --> 00:09:04,290 man kunne kalde feof eller ferror at informere brugeren om den specifikke begrundelse for spændende denne løkke. 157 00:09:04,290 --> 00:09:08,100 >> Skrivning til og læsning fra en fil er på sit mest basale, 158 00:09:08,100 --> 00:09:10,150 en simpel 3-delt proces. 159 00:09:10,150 --> 00:09:12,530 Først skal vi åbne filen. 160 00:09:12,530 --> 00:09:16,740 For det andet har vi lagt nogle ting ind i vores fil eller tage nogle ting ud af det. 161 00:09:16,740 --> 00:09:19,200 For det tredje, vi lukker filen. 162 00:09:19,200 --> 00:09:21,170 De første og sidste dele er let. 163 00:09:21,170 --> 00:09:23,920 Den midterste del er, hvor tricky ting ligger. 164 00:09:23,920 --> 00:09:27,760 Og skønt under hætten vi altid gøre med en lang sekvens af nuller og ettaller, 165 00:09:27,760 --> 00:09:30,710 det hjælper når kodning at tilføje et lag af abstraktion 166 00:09:30,710 --> 00:09:35,350 der forvandler sekvensen til noget, mere ligner hvad vi er vant til at se. 167 00:09:35,350 --> 00:09:39,570 For eksempel, hvis vi arbejder med en 24-bit bitmap-fil 168 00:09:39,570 --> 00:09:43,290 vi vil sandsynligvis være at læse eller skrive tre bytes ad gangen. 169 00:09:43,290 --> 00:09:46,450 I så fald, ville det være fornuftigt at definere og passende navn 170 00:09:46,450 --> 00:09:48,980 en struct, der er 3 bytes stor. 171 00:09:48,980 --> 00:09:51,410 >> Selvom arbejde med filer kan synes kompliceret, 172 00:09:51,410 --> 00:09:54,530 udnytte dem tillader os at gøre noget virkelig bemærkelsesværdig. 173 00:09:54,530 --> 00:09:58,880 Vi kan ændre verdens tilstand uden for vores program, 174 00:09:58,880 --> 00:10:01,730 kan vi skabe noget, der lever uden for livet for vores program, 175 00:10:01,730 --> 00:10:07,190 eller vi kan endda ændre noget, der blev oprettet før vores program begyndte at løbe. 176 00:10:07,190 --> 00:10:11,210 Samspil med filer er en virkelig kraftfuld del af programmeringen i C. 177 00:10:11,210 --> 00:10:15,300 og jeg er spændt på at se, hvad du vil lave med det i koden til at komme. 178 00:10:15,300 --> 00:10:19,770 Mit navn er Jason Hirschhorn. Det er CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [Latter] 181 00:10:25,940 --> 00:10:29,330 Okay. Man tager. Her går vi. 182 00:10:49,000 --> 00:10:52,140 Når vi tænker på en fil - >> Oh, vent. Undskyld. 183 00:10:52,140 --> 00:10:56,800 [Latter] Okay. 184 00:11:06,620 --> 00:11:09,970 Hej der. 185 00:11:13,670 --> 00:11:16,310 Når vi tænker på en fil - 186 00:11:17,610 --> 00:11:20,710 Når du tænker på en fil - Okay. Fortæl mig når du er klar. 187 00:11:20,710 --> 00:11:22,520 Åh, godt. 188 00:11:22,520 --> 00:11:26,180 Selvom læsning fra en teleprompter kan virke - nej. Min dårlige.