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 [Questo è CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 Quando pensiamo a un file, quello che viene in mente è un documento di Microsoft Word, 5 00:00:11,000 --> 00:00:14,000 un'immagine JPEG, o un brano MP3, 6 00:00:14,000 --> 00:00:17,000 e interagire con ciascuno di questi tipi di file in modi diversi. 7 00:00:17,000 --> 00:00:20,000 Ad esempio, in un documento Word aggiungiamo testo 8 00:00:20,000 --> 00:00:24,000 mentre con un'immagine JPEG potremmo ritagliare i bordi o ritoccare i colori. 9 00:00:24,000 --> 00:00:28,000 Eppure, sotto il cofano di tutti i file nel nostro computer non sono altro 10 00:00:28,000 --> 00:00:31,000 di una lunga sequenza di zero e uno. 11 00:00:31,000 --> 00:00:33,000 È alla specifica applicazione che interagisce con il file 12 00:00:33,000 --> 00:00:38,000 per decidere come elaborare questa lunga sequenza e lo presenta per l'utente. 13 00:00:38,000 --> 00:00:41,000 Da un lato, un documento può guardare solo un byte, 14 00:00:41,000 --> 00:00:45,000 o 8 zero e uno, e visualizzare un carattere ASCII sullo schermo. 15 00:00:45,000 --> 00:00:48,000 D'altra parte, una immagine bitmap può guardare 3 byte, 16 00:00:48,000 --> 00:00:50,000 o 24 zero e uno, 17 00:00:50,000 --> 00:00:53,000 e li interpretano come 3 numeri esadecimali 18 00:00:53,000 --> 00:00:56,000 che rappresentano i valori di rosso, verde e blu 19 00:00:56,000 --> 00:00:58,000 a un pixel di un'immagine. 20 00:00:58,000 --> 00:01:01,000 Qualunque cosa può apparire come sullo schermo, nella loro essenza, 21 00:01:01,000 --> 00:01:05,000 i file non sono altro che una sequenza di zero e uno. 22 00:01:05,000 --> 00:01:08,000 Quindi cerchiamo di immersione e di vedere come in realtà abbiamo manipolare questi zero e uno 23 00:01:08,000 --> 00:01:12,000 quando si tratta di scrittura e la lettura da un file. 24 00:01:12,000 --> 00:01:15,000 >> Inizierò suddividendolo in un semplice processo in 3 parti. 25 00:01:15,000 --> 00:01:19,000 Successivamente, verrà tuffarsi in due esempi di codice che illustrano queste tre parti. 26 00:01:19,000 --> 00:01:23,000 Infine, esamineremo il processo e alcuni dei suoi più importanti. 27 00:01:23,000 --> 00:01:25,000 Come con qualsiasi file che si trova sul desktop, 28 00:01:25,000 --> 00:01:28,000 la prima cosa da fare è aprirlo. 29 00:01:28,000 --> 00:01:31,000 In C facciamo dichiarando un puntatore ad una struct predefinito 30 00:01:31,000 --> 00:01:33,000 che rappresenta un file su disco. 31 00:01:33,000 --> 00:01:38,460 In questa chiamata di funzione, anche noi decidere se vogliamo scrivere o leggere dal file. 32 00:01:38,460 --> 00:01:41,660 Quindi, facciamo la lettura effettiva e la scrittura. 33 00:01:41,660 --> 00:01:44,800 Ci sono un certo numero di funzioni specializzate possiamo usare in questa parte, 34 00:01:44,800 --> 00:01:48,790 e quasi tutti iniziano con la lettera F, che sta per file. 35 00:01:48,790 --> 00:01:53,560 Infine, simile alle X rosse nell'angolo in alto dei file aperti sul computer, 36 00:01:53,560 --> 00:01:56,680 chiudiamo il file con una chiamata di funzione finale. 37 00:01:56,680 --> 00:01:59,540 Ora che abbiamo un'idea generale di ciò che andremo a fare, 38 00:01:59,540 --> 00:02:02,000 tuffiamoci nel codice. 39 00:02:02,000 --> 00:02:06,100 >> In questa directory, ci sono due file C e dei loro file eseguibili corrispondenti. 40 00:02:06,100 --> 00:02:09,710 Il programma di macchina da scrivere accetta un argomento della riga di comando, 41 00:02:09,710 --> 00:02:12,060 il nome del documento che si vuole creare. 42 00:02:12,060 --> 00:02:16,160 In questo caso, che chiameremo doc.txt. 43 00:02:16,160 --> 00:02:19,080 Corriamo il programma e inserire un paio di righe. 44 00:02:19,080 --> 00:02:23,660 Ciao. Il mio nome è Jason. 45 00:02:23,660 --> 00:02:26,710 Infine, bisogna digitare "quit". 46 00:02:26,710 --> 00:02:29,720 Se ora elencare tutti i file in questa directory, 47 00:02:29,720 --> 00:02:33,770 vediamo che esiste un nuovo documento chiamato doc.txt. 48 00:02:34,190 --> 00:02:36,110 Questo è il file di questo programma appena creato. 49 00:02:36,110 --> 00:02:40,520 E, naturalmente, è troppo altro che una lunga sequenza di zero e uno. 50 00:02:41,100 --> 00:02:43,260 Se apriamo questo nuovo file, 51 00:02:43,260 --> 00:02:45,870 vediamo le 3 righe di codice che abbiamo inserito nel nostro programma - 52 00:02:46,060 --> 00:02:49,060 Ciao. Nome maggio è Jason. 53 00:02:49,580 --> 00:02:52,090 Ma quello che sta realmente accadendo quando typewriter.c corre? 54 00:02:52,810 --> 00:02:55,520 La prima linea di interesse per noi è la linea 24. 55 00:02:55,560 --> 00:02:58,490 In questa linea, dichiariamo il nostro puntatore al file. 56 00:02:59,080 --> 00:03:03,140 La funzione che restituisce il puntatore, fopen, accetta due argomenti. 57 00:03:03,140 --> 00:03:07,440 Il primo è il nome del file inclusa l'estensione, se del caso. 58 00:03:07,440 --> 00:03:10,980 Ricordiamo che un'estensione di file non influenza il file al suo livello più basso. 59 00:03:10,980 --> 00:03:14,640 Siamo sempre a che fare con una lunga sequenza di zero e uno. 60 00:03:14,640 --> 00:03:19,630 Ma lo fa influenza come i file vengono interpretati e quali applicazioni vengono utilizzate per aprirli. 61 00:03:19,630 --> 00:03:22,290 Il secondo argomento di fopen è una singola lettera 62 00:03:22,290 --> 00:03:25,300 che si distingue per quello che abbiamo in programma di fare dopo che aprire il file. 63 00:03:25,300 --> 00:03:30,630 Ci sono tre opzioni per questo argomento - W, R, e A. 64 00:03:30,630 --> 00:03:34,900 Abbiamo scelto w in questo caso perché vogliamo scrivere nel file. 65 00:03:34,900 --> 00:03:38,820 R, come si può intuire, è per la lettura del file. 66 00:03:38,820 --> 00:03:41,760 E una è per l'aggiunta al file. 67 00:03:41,760 --> 00:03:44,960 Mentre sia w e può essere utilizzato per la scrittura di file, 68 00:03:44,960 --> 00:03:47,460 w Inizieremo scrivendo dall'inizio del file 69 00:03:47,460 --> 00:03:50,810 e potenzialmente sovrascrivere tutti i dati che sono stati precedentemente memorizzati. 70 00:03:50,810 --> 00:03:54,070 Per impostazione predefinita, il file si apre, se non esiste già, 71 00:03:54,070 --> 00:03:57,180 viene creato nella directory di lavoro corrente. 72 00:03:57,180 --> 00:04:00,540 Tuttavia, se vogliamo accedere o creare un file in una posizione diversa, 73 00:04:00,540 --> 00:04:02,650 nel primo argomento di fopen, 74 00:04:02,650 --> 00:04:05,840 si può specificare un percorso di file, oltre al nome del file. 75 00:04:05,840 --> 00:04:09,490 Mentre la prima parte di questo processo è solo una linea di codice lungo, 76 00:04:09,490 --> 00:04:12,350 è sempre buona norma includere un altro insieme di linee 77 00:04:12,350 --> 00:04:15,930 che controllare che il file è stato aperto o creato. 78 00:04:15,930 --> 00:04:20,300 Se fopen restituisce il valore null, che non vorrebbe andare avanti con il nostro programma, 79 00:04:20,300 --> 00:04:23,270 e questo può accadere se il sistema è operativo su memoria 80 00:04:23,270 --> 00:04:27,940 o se si tenta di aprire un file in una directory per la quale non abbiamo avuto i giusti permessi. 81 00:04:27,940 --> 00:04:31,780 >> La seconda parte del processo avviene in ciclo while macchina da scrivere. 82 00:04:31,780 --> 00:04:35,000 Usiamo un CS50 funzione di libreria per ricevere l'input da parte dell'utente, 83 00:04:35,000 --> 00:04:37,190 e assumendo che non si vuole uscire dal programma, 84 00:04:37,190 --> 00:04:41,940 usiamo le fputs funzione per prendere la stringa e scrivere al file. 85 00:04:41,940 --> 00:04:46,700 fputs è solo una delle tante funzioni che potremmo usare per scrivere nel file. 86 00:04:46,700 --> 00:04:51,920 Altri includono fwrite, fputc, e anche fprintf. 87 00:04:51,920 --> 00:04:54,840 Indipendentemente dalla particolare funzione si finisce per utilizzare, però, 88 00:04:54,840 --> 00:04:57,480 tutti hanno bisogno di sapere, attraverso i loro argomenti, 89 00:04:57,480 --> 00:04:59,670 almeno due cose - 90 00:04:59,670 --> 00:05:03,140 ciò che deve essere scritto e dove deve essere scritto. 91 00:05:03,140 --> 00:05:07,240 Nel nostro caso, l'ingresso è la stringa che deve essere scritto 92 00:05:07,240 --> 00:05:11,290 e fp è un puntatore che ci indirizza al punto in cui stiamo scrivendo. 93 00:05:11,290 --> 00:05:15,330 In questo programma, la seconda parte del processo è piuttosto semplice. 94 00:05:15,330 --> 00:05:17,360 Stiamo semplicemente prendendo una stringa dall'utente 95 00:05:17,360 --> 00:05:22,120 e l'aggiunta direttamente al nostro file con poco-a-no di convalida dell'input o controlli di sicurezza. 96 00:05:22,120 --> 00:05:26,160 Spesso, tuttavia, la seconda parte si occupano la maggior parte del codice. 97 00:05:26,160 --> 00:05:30,580 Infine, la terza parte è on line 58, in cui chiudiamo il file. 98 00:05:30,580 --> 00:05:34,860 Qui chiamiamo fclose e passare il nostro puntatore del file originale. 99 00:05:34,860 --> 00:05:39,500 Nella riga successiva, si ritorna a zero, che segna la fine del nostro programma. 100 00:05:39,500 --> 00:05:42,630 E, sì, la terza parte è così semplice come sembra. 101 00:05:42,630 --> 00:05:45,260 >> Passiamo alla lettura da file. 102 00:05:45,260 --> 00:05:48,220 Nel nostro elenco abbiamo un file chiamato printer.c. 103 00:05:48,220 --> 00:05:50,910 Facciamo correre con il file che abbiamo appena creato - 104 00:05:50,910 --> 00:05:53,350 doc.txt. 105 00:05:53,350 --> 00:05:58,150 Questo programma, come suggerisce il nome, semplicemente stampare il contenuto del file passato. 106 00:05:58,150 --> 00:06:00,230 E non l'abbiamo. 107 00:06:00,230 --> 00:06:03,780 Le righe di codice che avevamo scritto in precedenza e salvato in doc.txt. 108 00:06:03,780 --> 00:06:06,980 Ciao. Il mio nome è Jason. 109 00:06:06,980 --> 00:06:09,120 Se ci immergiamo in printer.c, 110 00:06:09,120 --> 00:06:13,570 si vede che un sacco di codice è simile a quello che abbiamo appena attraversato in typewriter.c. 111 00:06:13,570 --> 00:06:16,720 Infatti linea 22, dove abbiamo aperto il file, 112 00:06:16,720 --> 00:06:19,220 e la linea 39, dove abbiamo chiuso il file, 113 00:06:19,220 --> 00:06:23,890 sono entrambi quasi identica a typewriter.c, salvo argomento fopen secondo. 114 00:06:23,890 --> 00:06:26,510 Questa volta stiamo leggendo da un file, 115 00:06:26,510 --> 00:06:29,040 così abbiamo scelto r invece di w. 116 00:06:29,040 --> 00:06:31,950 Così, concentriamoci sulla seconda parte del processo. 117 00:06:31,950 --> 00:06:36,060 In linea 35, la seconda condizione nel nostro 4 loop, 118 00:06:36,060 --> 00:06:38,590 facciamo una chiamata a fgets, 119 00:06:38,590 --> 00:06:42,190 la funzione compagno di fputs da prima. 120 00:06:42,190 --> 00:06:44,660 Questa volta abbiamo tre argomenti. 121 00:06:44,660 --> 00:06:48,810 Il primo è il puntatore alla matrice di caratteri in cui la stringa verranno memorizzati. 122 00:06:48,810 --> 00:06:52,670 Il secondo è il numero massimo di caratteri da leggere. 123 00:06:52,670 --> 00:06:56,010 E il terzo è il puntatore al file con il quale stiamo lavorando. 124 00:06:56,010 --> 00:07:00,780 Si noterà che il ciclo for termina quando fgets restituisce null. 125 00:07:00,780 --> 00:07:02,940 Ci sono due motivi che ciò possa essere accaduto. 126 00:07:02,940 --> 00:07:05,380 In primo luogo, un errore potrebbe essersi verificato. 127 00:07:05,380 --> 00:07:10,740 Secondo, e più probabilmente, alla fine del file è stato raggiunto e più caratteri sono stati letti. 128 00:07:10,740 --> 00:07:14,040 Nel caso vi stiate chiedendo, due funzioni esistono che ci permettono di dire 129 00:07:14,040 --> 00:07:17,160 che la ragione è la causa di questo puntatore nullo particolare. 130 00:07:17,160 --> 00:07:21,090 E, non a caso, dal momento che hanno a che fare con il lavoro con i file, 131 00:07:21,090 --> 00:07:26,940 sia la funzione ferror e l'inizio funzione feof con la lettera f. 132 00:07:26,940 --> 00:07:32,130 >> Infine, prima di concludere, una breve nota sulla fine della funzione di file, 133 00:07:32,130 --> 00:07:36,690 che, come appena detto, è scritto come feof. 134 00:07:36,690 --> 00:07:41,550 Spesso vi troverete con while e for cicli di leggere progressivamente il vostro senso attraverso i file. 135 00:07:41,550 --> 00:07:45,790 Quindi, avrete bisogno di un modo per porre fine a queste loop dopo aver raggiunto la fine di questi file. 136 00:07:45,790 --> 00:07:50,510 Chiamare feof sul vostro puntatore del file e controllare per vedere se è vero 137 00:07:50,510 --> 00:07:52,310 avrebbe fatto proprio questo. 138 00:07:52,310 --> 00:07:59,820 Così, un ciclo while con la condizione (! Feof (fp)) potrebbe sembrare una soluzione perfettamente adeguata. 139 00:07:59,820 --> 00:08:03,770 Tuttavia, dire che abbiamo una linea a sinistra nel nostro file di testo. 140 00:08:03,770 --> 00:08:07,130 Ci entrare nel nostro ciclo while e tutto funzionerà come previsto. 141 00:08:07,130 --> 00:08:12,750 Nel round successivo attraverso, il nostro programma verificherà se feof di fp è vero, 142 00:08:12,750 --> 00:08:15,430 ma - e questo è il punto cruciale da capire - 143 00:08:15,430 --> 00:08:17,770 non sarà vero per il momento. 144 00:08:17,770 --> 00:08:21,110 Questo perché l'obiettivo di feof non è quello di verificare 145 00:08:21,110 --> 00:08:24,400 se la chiamata successiva a una funzione leggere colpirà la fine del file, 146 00:08:24,400 --> 00:08:28,190 ma piuttosto di verificare se la fine del file è già stato raggiunto. 147 00:08:28,190 --> 00:08:30,140 Nel caso di questo esempio, 148 00:08:30,140 --> 00:08:32,780 leggere l'ultima riga del nostro file va perfettamente senza intoppi, 149 00:08:32,780 --> 00:08:36,210 ma il programma non sa ancora che abbiamo colpito la fine del nostro file. 150 00:08:36,210 --> 00:08:40,549 Solo quando lo fa una lettura supplementari che neutralizza la fine del file. 151 00:08:40,549 --> 00:08:43,210 Pertanto, una condizione corretta sarebbe il seguente: 152 00:08:43,210 --> 00:08:49,330 fgets e le sue tre argomenti - di uscita, dimensioni della produzione, e FP - 153 00:08:49,330 --> 00:08:52,570 e tutto questo non uguale a null. 154 00:08:52,570 --> 00:08:55,260 Questo è l'approccio che abbiamo adottato in printer.c, 155 00:08:55,260 --> 00:08:57,890 e in questo caso, dopo il ciclo termina, 156 00:08:57,890 --> 00:09:04,290 si potrebbe chiamare feof o ferror per informare l'utente circa la motivazione specifica per uscire questo ciclo. 157 00:09:04,290 --> 00:09:08,100 >> La scrittura e la lettura da un file è, nella sua forma più semplice, 158 00:09:08,100 --> 00:09:10,150 un semplice processo in 3 parti. 159 00:09:10,150 --> 00:09:12,530 Per prima cosa, apriamo il file. 160 00:09:12,530 --> 00:09:16,740 In secondo luogo, abbiamo messo alcune cose nel nostro file o prendere alcune cose fuori di esso. 161 00:09:16,740 --> 00:09:19,200 In terzo luogo, chiudere il file. 162 00:09:19,200 --> 00:09:21,170 La prima e l'ultima sono facili. 163 00:09:21,170 --> 00:09:23,920 La parte centrale è dove si trova la roba difficile. 164 00:09:23,920 --> 00:09:27,760 E anche se sotto il cofano ci stiamo sempre a che fare con una lunga sequenza di zero e uno, 165 00:09:27,760 --> 00:09:30,710 non aiutano quando si scrive codice per aggiungere un livello di astrazione 166 00:09:30,710 --> 00:09:35,350 che trasforma la sequenza in qualcosa che assomiglia più da vicino quello che siamo abituati a vedere. 167 00:09:35,350 --> 00:09:39,570 Per esempio, se stiamo lavorando con un 24-bit file bitmap, 168 00:09:39,570 --> 00:09:43,290 saremo probabilmente leggere o scrivere tre byte alla volta. 169 00:09:43,290 --> 00:09:46,450 In tal caso, non avrebbe molto senso per definire e assegnare un nome appropriato 170 00:09:46,450 --> 00:09:48,980 una struttura che si trova a 3 byte di grandi dimensioni. 171 00:09:48,980 --> 00:09:51,410 >> Anche se si lavora con file può sembrare complicato, 172 00:09:51,410 --> 00:09:54,530 utilizzarli ci permette di fare qualcosa di veramente notevole. 173 00:09:54,530 --> 00:09:58,880 Siamo in grado di modificare lo stato del mondo esterno il nostro programma, 174 00:09:58,880 --> 00:10:01,730 siamo in grado di creare qualcosa che vive al di là della vita del nostro programma, 175 00:10:01,730 --> 00:10:07,190 o si può anche cambiare qualcosa che è stato creato prima del nostro programma è stato avviato in esecuzione. 176 00:10:07,190 --> 00:10:11,210 Interagire con i file è una parte davvero potente della programmazione in C. 177 00:10:11,210 --> 00:10:15,300 e io sono felice di vedere che cosa si sta andando a creare con essa nel codice a venire. 178 00:10:15,300 --> 00:10:19,770 Il mio nome è Jason Hirschhorn. Questo è CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [Risate] 181 00:10:25,940 --> 00:10:29,330 Va bene. Un prendere. Ci siamo. 182 00:10:49,000 --> 00:10:52,140 Quando pensiamo a un file - >> Oh, aspetta. Scusi. 183 00:10:52,140 --> 00:10:56,800 [Risate] Ok. 184 00:11:06,620 --> 00:11:09,970 Hey there. 185 00:11:13,670 --> 00:11:16,310 Quando pensiamo a un file - 186 00:11:17,610 --> 00:11:20,710 Quando si pensa di un file - Ok. Dimmi quando sei pronto. 187 00:11:20,710 --> 00:11:22,520 Oh, fantastico. 188 00:11:22,520 --> 00:11:26,180 Anche se la lettura da un gobbo può sembrare - n. Il mio male.