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 [Aquesta és CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 Quan pensem en un arxiu, el que ve a la ment és un document de Microsoft Word, 5 00:00:11,000 --> 00:00:14,000 una imatge JPEG, o una cançó MP3, 6 00:00:14,000 --> 00:00:17,000 i ens relacionem amb cada un d'aquests tipus d'arxius de diferents maneres. 7 00:00:17,000 --> 00:00:20,000 Per exemple, en un document de Word afegir el text 8 00:00:20,000 --> 00:00:24,000 mentre que amb una imatge JPEG que podríem retallar les vores o retocar els colors. 9 00:00:24,000 --> 00:00:28,000 No obstant això, sota el capó de tots els arxius en el nostre ordinador no són més 10 00:00:28,000 --> 00:00:31,000 d'una llarga seqüència de zeros i uns. 11 00:00:31,000 --> 00:00:33,000 Tot depèn de l'aplicació específica que interactua amb l'arxiu 12 00:00:33,000 --> 00:00:38,000 per decidir com processar aquesta seqüència llarga i presentar-la al usuari. 13 00:00:38,000 --> 00:00:41,000 D'una banda, un document pot mirar a un sol byte, 14 00:00:41,000 --> 00:00:45,000 o 8 zeros i uns, i mostrar un caràcter ASCII a la pantalla. 15 00:00:45,000 --> 00:00:48,000 D'altra banda, una imatge de mapa de bits pot mirar a 3 bytes, 16 00:00:48,000 --> 00:00:50,000 o 24 zeros i uns, 17 00:00:50,000 --> 00:00:53,000 i les interpreten com tres nombres hexadecimals 18 00:00:53,000 --> 00:00:56,000 que representen els valors de vermell, verd i blau 19 00:00:56,000 --> 00:00:58,000 en un píxel d'una imatge. 20 00:00:58,000 --> 00:01:01,000 Diguin el que pot semblar a la pantalla, en el fons, 21 00:01:01,000 --> 00:01:05,000 arxius no són res més que una seqüència de zeros i uns. 22 00:01:05,000 --> 00:01:08,000 Així que anem a bussejar i veure com realment manipular aquests zeros i uns 23 00:01:08,000 --> 00:01:12,000 quan es tracta de l'escriptura i lectura d'un arxiu. 24 00:01:12,000 --> 00:01:15,000 >> Vaig a començar per el descomponen en un simple procés de 3 parts. 25 00:01:15,000 --> 00:01:19,000 A continuació, vaig a bussejar en dos exemples de codi que mostren aquestes tres parts. 26 00:01:19,000 --> 00:01:23,000 Finalment, vaig a revisar el procés i alguns dels seus detalls més importants. 27 00:01:23,000 --> 00:01:25,000 Igual que amb qualsevol arxiu que seu al seu escriptori, 28 00:01:25,000 --> 00:01:28,000 el primer que ha de fer és obrir-lo. 29 00:01:28,000 --> 00:01:31,000 En C fem això en declarar un punter a una estructura predefinida 30 00:01:31,000 --> 00:01:33,000 que representa un arxiu en el disc. 31 00:01:33,000 --> 00:01:38,460 En aquesta crida de funció, també decidim si volem escriure o llegir des del fitxer. 32 00:01:38,460 --> 00:01:41,660 A continuació, fem la lectura real i l'escriptura. 33 00:01:41,660 --> 00:01:44,800 Hi ha una sèrie de funcions especialitzades que podem utilitzar en aquesta part, 34 00:01:44,800 --> 00:01:48,790 i gairebé tots ells comencen amb la lletra F, que correspon a arxiu. 35 00:01:48,790 --> 00:01:53,560 Finalment, semblant a la petita X vermella a l'extrem superior dels arxius oberts a l'equip, 36 00:01:53,560 --> 00:01:56,680 tanquem l'arxiu amb una crida a la funció final. 37 00:01:56,680 --> 00:01:59,540 Ara que tenim una idea general del que farem, 38 00:01:59,540 --> 00:02:02,000 anem a bussejar en el codi. 39 00:02:02,000 --> 00:02:06,100 >> En aquest directori, tenim dos arxius de C i els fitxers executables corresponents. 40 00:02:06,100 --> 00:02:09,710 El programa de màquina d'escriure té un argument de línia d'ordres, 41 00:02:09,710 --> 00:02:12,060 el nom del document que voleu crear. 42 00:02:12,060 --> 00:02:16,160 En aquest cas, anem a dir-doc.txt. 43 00:02:16,160 --> 00:02:19,080 Anem a executar el programa i entrar en un parell de línies. 44 00:02:19,080 --> 00:02:23,660 Hi. El meu nom és Jason. 45 00:02:23,660 --> 00:02:26,710 Finalment, escriurem "quit". 46 00:02:26,710 --> 00:02:29,720 Si ara una llista de tots els arxius en aquest directori, 47 00:02:29,720 --> 00:02:33,770 veiem que hi ha un nou document anomenat doc.txt. 48 00:02:34,190 --> 00:02:36,110 Aquest és l'arxiu d'aquest programa acaba de crear. 49 00:02:36,110 --> 00:02:40,520 I, per descomptat, també no és més que una llarga seqüència de zeros i uns. 50 00:02:41,100 --> 00:02:43,260 Si obrim aquest nou arxiu, 51 00:02:43,260 --> 00:02:45,870 veiem les 3 línies de codi que va entrar en el nostre programa - 52 00:02:46,060 --> 00:02:49,060 Hi. Maig és el nom de Jason. 53 00:02:49,580 --> 00:02:52,090 Però el que realment succeeix quan s'executa typewriter.c? 54 00:02:52,810 --> 00:02:55,520 La primera línia d'interès per a nosaltres és la línia 24. 55 00:02:55,560 --> 00:02:58,490 En aquesta línia, declarem el nostre punter d'arxiu. 56 00:02:59,080 --> 00:03:03,140 La funció que retorna aquest indicador, fopen, pren dos arguments. 57 00:03:03,140 --> 00:03:07,440 El primer és el nom de l'arxiu incloent l'extensió d'arxiu si és apropiat. 58 00:03:07,440 --> 00:03:10,980 Recordem que una extensió d'arxiu no influeix en l'arxiu en el seu nivell més baix. 59 00:03:10,980 --> 00:03:14,640 Sempre estem tractant amb una llarga seqüència de zeros i uns. 60 00:03:14,640 --> 00:03:19,630 Però sí influeixen en com s'interpreten els arxius i les aplicacions que s'utilitzen per obrir-los. 61 00:03:19,630 --> 00:03:22,290 El segon argument d'fopen és una sola lletra 62 00:03:22,290 --> 00:03:25,300 que representa el que pensa fer després d'obrir l'arxiu. 63 00:03:25,300 --> 00:03:30,630 Hi ha tres opcions per aquest argument - W, R i A. 64 00:03:30,630 --> 00:03:34,900 Hem triat w en aquest cas perquè volem escriure a l'arxiu. 65 00:03:34,900 --> 00:03:38,820 R, com vostè probablement pot endevinar, és per llegir l'arxiu. 66 00:03:38,820 --> 00:03:41,760 I una és per annexar a la imatge. 67 00:03:41,760 --> 00:03:44,960 Mentrestant w i una pot ser utilitzat per escriure en arxius, 68 00:03:44,960 --> 00:03:47,460 w començarà a escriure des del principi de l'arxiu 69 00:03:47,460 --> 00:03:50,810 i potencialment sobreescriure les dades que han estat prèviament emmagatzemats. 70 00:03:50,810 --> 00:03:54,070 Per defecte, l'arxiu s'obrirà si no existeix ja, 71 00:03:54,070 --> 00:03:57,180 es crea en el nostre directori de treball actual. 72 00:03:57,180 --> 00:04:00,540 No obstant això, si volem iniciar sessió o crear un arxiu a un altre lloc, 73 00:04:00,540 --> 00:04:02,650 en el primer argument de fopen, 74 00:04:02,650 --> 00:04:05,840 és possible especificar una ruta d'arxiu en addició al nom de fitxer. 75 00:04:05,840 --> 00:04:09,490 Mentre que la primera part d'aquest procés és només una línia de codi llarg, 76 00:04:09,490 --> 00:04:12,350 que sempre és una bona pràctica incloure una altra sèrie de línies 77 00:04:12,350 --> 00:04:15,930 El registre d'entrada per assegurar-se que l'arxiu s'ha obert correctament o creat. 78 00:04:15,930 --> 00:04:20,300 Si fopen retorna un valor nul, no volem seguir endavant amb el nostre programa, 79 00:04:20,300 --> 00:04:23,270 i això pot passar si el sistema operatiu no té memòria 80 00:04:23,270 --> 00:04:27,940 o si intenta obrir un arxiu en un directori per al qual no comptava amb els permisos adequats. 81 00:04:27,940 --> 00:04:31,780 >> La segona part del procés es realitza en bucle mentre que la màquina d'escriure. 82 00:04:31,780 --> 00:04:35,000 Nosaltres fem servir una funció de biblioteca CS50 per obtenir entrada de l'usuari, 83 00:04:35,000 --> 00:04:37,190 i assumint que no desitja sortir del programa, 84 00:04:37,190 --> 00:04:41,940 fem servir els fputs funció per prendre la cadena i escriure-la al arxiu. 85 00:04:41,940 --> 00:04:46,700 fputs és només una de les moltes funcions que podria utilitzar per escriure al fitxer. 86 00:04:46,700 --> 00:04:51,920 Altres inclouen fwrite, fputc i fprintf fins i tot. 87 00:04:51,920 --> 00:04:54,840 Independentment de la funció particular que acaben usant, però, 88 00:04:54,840 --> 00:04:57,480 tots ells necessiten saber, a través dels seus arguments, 89 00:04:57,480 --> 00:04:59,670 almenys dues coses - 90 00:04:59,670 --> 00:05:03,140 el que ha de ser per escrit i en el qual s'ha d'escriure. 91 00:05:03,140 --> 00:05:07,240 En el nostre cas, l'entrada és la cadena que necessita ser escrita 92 00:05:07,240 --> 00:05:11,290 i fp és el punter que ens porta a on estem escrivint. 93 00:05:11,290 --> 00:05:15,330 En aquest programa, la segona part del procés és bastant senzill. 94 00:05:15,330 --> 00:05:17,360 Simplement estem prenent una cadena de l'usuari 95 00:05:17,360 --> 00:05:22,120 i afegir directament al nostre arxiu amb poc o gens de validació d'entrada o controls de seguretat. 96 00:05:22,120 --> 00:05:26,160 Sovint, però, la segona part s'ocuparà de la major part del seu codi. 97 00:05:26,160 --> 00:05:30,580 Finalment, la tercera part està en la línia 58, on es tanca l'arxiu. 98 00:05:30,580 --> 00:05:34,860 Aquí anomenem fclose i passar-ho nostre apuntador d'arxiu original. 99 00:05:34,860 --> 00:05:39,500 En la línia següent, tornem a zero, el que indica el final del nostre programa. 100 00:05:39,500 --> 00:05:42,630 I, sí, la tercera part és tan simple com això. 101 00:05:42,630 --> 00:05:45,260 >> Anem a passar a la lectura dels arxius. 102 00:05:45,260 --> 00:05:48,220 De tornada al nostre directori tenim un arxiu anomenat printer.c. 103 00:05:48,220 --> 00:05:50,910 Anem a córrer amb l'arxiu que acabem de crear - 104 00:05:50,910 --> 00:05:53,350 doc.txt. 105 00:05:53,350 --> 00:05:58,150 Aquest programa, com el seu nom indica, simplement imprimir el contingut de l'arxiu se li ha passat. 106 00:05:58,150 --> 00:06:00,230 I aquí el tenim. 107 00:06:00,230 --> 00:06:03,780 Les línies de codi que havia escrit anteriorment i guardat en doc.txt. 108 00:06:03,780 --> 00:06:06,980 Hi. El meu nom és Jason. 109 00:06:06,980 --> 00:06:09,120 Si ens submergim en printer.c, 110 00:06:09,120 --> 00:06:13,570 veiem que una gran part del codi és similar al que pots anar caminant a través de typewriter.c. 111 00:06:13,570 --> 00:06:16,720 De fet la línia 22, on obrim l'arxiu, 112 00:06:16,720 --> 00:06:19,220 i la línia 39, on es va tancar l'expedient, 113 00:06:19,220 --> 00:06:23,890 són gairebé idèntics a typewriter.c, amb excepció d'argument fopen segon. 114 00:06:23,890 --> 00:06:26,510 Aquesta vegada estem llegint d'un arxiu, 115 00:06:26,510 --> 00:06:29,040 pel que hem triat en comptes de r w. 116 00:06:29,040 --> 00:06:31,950 Per tant, ens centrarem en la segona part del procés. 117 00:06:31,950 --> 00:06:36,060 En la línia 35, a la segona condició en nostre 4 loop, 118 00:06:36,060 --> 00:06:38,590 fem una crida a fgets, 119 00:06:38,590 --> 00:06:42,190 la funció fputs company d'abans. 120 00:06:42,190 --> 00:06:44,660 En aquesta ocasió comptem amb tres arguments. 121 00:06:44,660 --> 00:06:48,810 El primer és el punter a la matriu de caràcters en què s'emmagatzema la cadena. 122 00:06:48,810 --> 00:06:52,670 El segon és el nombre màxim de caràcters a llegir. 123 00:06:52,670 --> 00:06:56,010 I el tercer és el punter a l'arxiu amb el que estem treballant. 124 00:06:56,010 --> 00:07:00,780 Es donarà compte de que el bucle acaba quan fgets retorna null. 125 00:07:00,780 --> 00:07:02,940 Hi ha dues raons que això va poder haver succeït. 126 00:07:02,940 --> 00:07:05,380 En primer lloc, un error pot haver passat. 127 00:07:05,380 --> 00:07:10,740 En segon lloc, i més probablement, al final de l'arxiu es va aconseguir caràcters i no més llegir van ser. 128 00:07:10,740 --> 00:07:14,040 En cas que vostè s'estigui preguntant, no hi ha dues funcions que ens permeten comptar 129 00:07:14,040 --> 00:07:17,160 la qual cosa és la causa d'aquest punter nul en particular. 130 00:07:17,160 --> 00:07:21,090 I, com és lògic, ja que tenen a veure amb treballar amb els arxius, 131 00:07:21,090 --> 00:07:26,940 tant la funció ferror i la funció d'arrencada feof amb la lletra f. 132 00:07:26,940 --> 00:07:32,130 >> Finalment, abans de concloure, una breu nota sobre el final de la funció d'arxiu, 133 00:07:32,130 --> 00:07:36,690 que, com s'acaba d'esmentar, s'escriu com feof. 134 00:07:36,690 --> 00:07:41,550 Sovint et trobaràs amb bucles while i for a llegir progressivament el seu camí a través dels arxius. 135 00:07:41,550 --> 00:07:45,790 Per tant, vostè necessita una manera de posar fi a aquests bucles després d'arribar al final d'aquests arxius. 136 00:07:45,790 --> 00:07:50,510 Trucar a feof al punter de l'arxiu i la comprovació per veure si és veritat 137 00:07:50,510 --> 00:07:52,310 faria exactament això. 138 00:07:52,310 --> 00:07:59,820 Per tant, un bucle mentre la condició (! Feof (fp)) pot semblar una solució perfectament adequada. 139 00:07:59,820 --> 00:08:03,770 Però diguem que tenim una línia que queda al nostre arxiu de text. 140 00:08:03,770 --> 00:08:07,130 Entrarem en el nostre bucle while i tot sortirà segons el planejat. 141 00:08:07,130 --> 00:08:12,750 En la següent ronda a través del nostre programa comprovarà si feof de fp és cert, 142 00:08:12,750 --> 00:08:15,430 però - i aquest és el punt crucial entendre aquí - 143 00:08:15,430 --> 00:08:17,770 no serà veritat de moment. 144 00:08:17,770 --> 00:08:21,110 Això és perquè el propòsit de feof no és comprovar 145 00:08:21,110 --> 00:08:24,400 si la crida a una funció de lectura es prem el final de l'arxiu, 146 00:08:24,400 --> 00:08:28,190 sinó més aviat per comprovar si o no el final de l'arxiu ja s'ha assolit. 147 00:08:28,190 --> 00:08:30,140 En el cas d'aquest exemple, 148 00:08:30,140 --> 00:08:32,780 la lectura de l'última línia del nostre fitxer va perfectament sense problemes, 149 00:08:32,780 --> 00:08:36,210 però el programa encara no sap que hem arribat al final del nostre arxiu. 150 00:08:36,210 --> 00:08:40,549 No és fins que ho faci una lectura addicional que contraresta el final de l'arxiu. 151 00:08:40,549 --> 00:08:43,210 Així, una condició correcta seria la següent: 152 00:08:43,210 --> 00:08:49,330 fgets i els seus tres arguments - de sortida, mida de sortida i FP - 153 00:08:49,330 --> 00:08:52,570 i tot això no és igual a null. 154 00:08:52,570 --> 00:08:55,260 Aquest és l'enfocament que adoptem en printer.c, 155 00:08:55,260 --> 00:08:57,890 i en aquest cas, després de sortir del bucle, 156 00:08:57,890 --> 00:09:04,290 vostè pot trucar o feof ferror per informar a l'usuari sobre el raonament específic per sortir d'aquest bucle. 157 00:09:04,290 --> 00:09:08,100 >> Escriptura i lectura d'un arxiu és, en la seva forma més bàsica, 158 00:09:08,100 --> 00:09:10,150 un simple procés de 3 parts. 159 00:09:10,150 --> 00:09:12,530 En primer lloc, obrir el fitxer. 160 00:09:12,530 --> 00:09:16,740 En segon lloc, hem posat algunes coses en el nostre arxiu o prendre algunes coses d'ella. 161 00:09:16,740 --> 00:09:19,200 En tercer lloc, es tanca l'arxiu. 162 00:09:19,200 --> 00:09:21,170 Les parts primera i última són fàcils. 163 00:09:21,170 --> 00:09:23,920 La part central és on les coses es troba delicat. 164 00:09:23,920 --> 00:09:27,760 I encara que per sota de la caputxa que sempre estem tractant amb una llarga seqüència de zeros i uns, 165 00:09:27,760 --> 00:09:30,710 si ajuda al codificar per afegir una capa d'abstracció 166 00:09:30,710 --> 00:09:35,350 que converteix la seqüència en alguna cosa que s'assembla més al que estem acostumats a veure. 167 00:09:35,350 --> 00:09:39,570 Per exemple, si estem treballant amb un arxiu de mapa de bits de 24-bit, 168 00:09:39,570 --> 00:09:43,290 que probablement va a llegir o escriure tres bytes alhora. 169 00:09:43,290 --> 00:09:46,450 En aquest cas, tindria sentit per definir i nomenar apropiadament 170 00:09:46,450 --> 00:09:48,980 una estructura que és de 3 bytes de grans dimensions. 171 00:09:48,980 --> 00:09:51,410 >> Tot i treballar amb arxius pot semblar complicat, 172 00:09:51,410 --> 00:09:54,530 la utilització d'ells ens permet fer alguna cosa veritablement notable. 173 00:09:54,530 --> 00:09:58,880 Podem canviar l'estat del món fora del nostre programa, 174 00:09:58,880 --> 00:10:01,730 podem crear alguna cosa que viu més enllà de la vida del nostre programa, 175 00:10:01,730 --> 00:10:07,190 o fins i tot podem canviar alguna cosa que es va crear abans que el nostre programa va començar a córrer. 176 00:10:07,190 --> 00:10:11,210 Interactuar amb els arxius és una part realment de gran abast de la programació en C. 177 00:10:11,210 --> 00:10:15,300 i estic emocionat de veure el que crearem amb ella en el codi per venir. 178 00:10:15,300 --> 00:10:19,770 El meu nom és Jason Hirschhorn. Això és CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [Rialles] 181 00:10:25,940 --> 00:10:29,330 Bé. Una sola presa. Aquí anem. 182 00:10:49,000 --> 00:10:52,140 Quan pensem en un arxiu - >> Oh, espera. Em sap greu. 183 00:10:52,140 --> 00:10:56,800 [Rialles] Bé. 184 00:11:06,620 --> 00:11:09,970 Hey there. 185 00:11:13,670 --> 00:11:16,310 Quan pensem en un arxiu - 186 00:11:17,610 --> 00:11:20,710 Quan vostè pensa en un arxiu - D'acord. Digues quan estiguis llest. 187 00:11:20,710 --> 00:11:22,520 Oh, genial. 188 00:11:22,520 --> 00:11:26,180 Encara que la lectura d'un teleprompter pot semblar - no. La meva malament.