1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [Plik I / O] 2 00:00:02,000 --> 00:00:04,000 [Jason Hirschhorn, Harvard University] 3 00:00:04,000 --> 00:00:07,000 [To jest CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 Kiedy myślimy o pliku, co przychodzi do głowy to dokument Microsoft Word, 5 00:00:11,000 --> 00:00:14,000 obraz JPEG lub MP3 song, 6 00:00:14,000 --> 00:00:17,000 i współdziałają z każdym z tych typów plików na różne sposoby. 7 00:00:17,000 --> 00:00:20,000 Na przykład, w dokumencie programu Word możemy dodać tekst 8 00:00:20,000 --> 00:00:24,000 podczas gdy z obrazu JPEG możemy przyciąć się krawędzie lub retuszować kolory. 9 00:00:24,000 --> 00:00:28,000 Jednak pod maską wszystkie pliki w naszym komputerze nie są niczym więcej 10 00:00:28,000 --> 00:00:31,000 niż długi ciąg zer i jedynek. 11 00:00:31,000 --> 00:00:33,000 To jest do konkretnego zastosowania, który współdziała z plikiem 12 00:00:33,000 --> 00:00:38,000 zdecydować, jak przetworzyć ten długiej sekwencji i przedstawić go do użytkownika. 13 00:00:38,000 --> 00:00:41,000 Z jednej strony, dokument może spojrzeć na jednym bajcie, 14 00:00:41,000 --> 00:00:45,000 lub 8 zer i jedynek, a wyświetlanie znaków ASCII na ekranie. 15 00:00:45,000 --> 00:00:48,000 Z drugiej strony, może wyglądać bitmapy w 3 bajtów 16 00:00:48,000 --> 00:00:50,000 lub 24 zer i jedynek, 17 00:00:50,000 --> 00:00:53,000 i interpretować je jako 3 liczb szesnastkowych 18 00:00:53,000 --> 00:00:56,000 które reprezentują wartości dla koloru czerwonego, zielonego i niebieskiego 19 00:00:56,000 --> 00:00:58,000 jednego piksela obrazu. 20 00:00:58,000 --> 00:01:01,000 Cokolwiek oni wyglądają na ekranie, na ich rdzenia, 21 00:01:01,000 --> 00:01:05,000 Pliki nie są niczym więcej niż ciąg zer i jedynek. 22 00:01:05,000 --> 00:01:08,000 Więc zanurkować i patrzeć na to, jak rzeczywiście manipulować zer i jedynek 23 00:01:08,000 --> 00:01:12,000 jeśli chodzi o piśmie i odczytu z pliku. 24 00:01:12,000 --> 00:01:15,000 >> Zacznę od podziału go do prostego 3-część procesu. 25 00:01:15,000 --> 00:01:19,000 Następnie będę nurkować na dwa przykłady kodu, które wykażą te trzy części. 26 00:01:19,000 --> 00:01:23,000 Wreszcie będę przeglądu procesu, a niektóre z jego szczegółami najważniejszych. 27 00:01:23,000 --> 00:01:25,000 Jak w przypadku każdego pliku, który znajduje się na pulpicie, 28 00:01:25,000 --> 00:01:28,000 Pierwszą rzeczą do zrobienia jest, aby go otworzyć. 29 00:01:28,000 --> 00:01:31,000 W C to zrobić deklarując wskaźnik do predefiniowanej struktury 30 00:01:31,000 --> 00:01:33,000 że reprezentuje plik na dysku. 31 00:01:33,000 --> 00:01:38,460 W tym wywołaniu funkcji, możemy także zdecydować, czy chcemy napisać lub odczytać pliku. 32 00:01:38,460 --> 00:01:41,660 Dalej, mamy rzeczywisty czytania i pisania. 33 00:01:41,660 --> 00:01:44,800 Istnieje wiele specjalizowanych funkcji można stosować w tej części, 34 00:01:44,800 --> 00:01:48,790 i prawie wszystkie z nich zaczynają się od litery F, co oznacza plik. 35 00:01:48,790 --> 00:01:53,560 Ostatnia, zbliżona do The Little Red X w górnym rogu pliki otworzyć na komputerze, 36 00:01:53,560 --> 00:01:56,680 zamykamy plik z ostatnim wywołaniu funkcji. 37 00:01:56,680 --> 00:01:59,540 Teraz, gdy mamy ogólne pojęcie o tym, co będziemy robić, 38 00:01:59,540 --> 00:02:02,000 niech nurkować do kodu. 39 00:02:02,000 --> 00:02:06,100 >> W tym katalogu mamy dwa pliki C i odpowiadające im pliki wykonywalne. 40 00:02:06,100 --> 00:02:09,710 Program typewriter przyjmuje jeden argument wiersza poleceń, 41 00:02:09,710 --> 00:02:12,060 Nazwa dokumentu chcemy stworzyć. 42 00:02:12,060 --> 00:02:16,160 W tym przypadku, będziemy nazywać Doc.txt. 43 00:02:16,160 --> 00:02:19,080 Załóżmy, uruchomić program i wprowadzić kilka linii. 44 00:02:19,080 --> 00:02:23,660 Hi. Nazywam się Jason. 45 00:02:23,660 --> 00:02:26,710 Wreszcie będziemy wpisz "quit". 46 00:02:26,710 --> 00:02:29,720 Jeśli teraz listę wszystkich plików w tym katalogu, 47 00:02:29,720 --> 00:02:33,770 widzimy, że nowy dokument istnieje nazywa Doc.txt. 48 00:02:34,190 --> 00:02:36,110 To plik ten program po prostu stworzony. 49 00:02:36,110 --> 00:02:40,520 I oczywiście, to też nie jest niczym więcej niż długi ciąg zer i jedynek. 50 00:02:41,100 --> 00:02:43,260 Jeśli otworzyć nowy plik, 51 00:02:43,260 --> 00:02:45,870 możemy zobaczyć 3 linie kodu weszliśmy do naszego programu - 52 00:02:46,060 --> 00:02:49,060 Hi. Nazwa maja jest Jason. 53 00:02:49,580 --> 00:02:52,090 Ale co się właściwie dzieje, gdy typewriter.c działa? 54 00:02:52,810 --> 00:02:55,520 Pierwsza linia interesujące dla nas jest linia 24. 55 00:02:55,560 --> 00:02:58,490 W tym wierszu deklarujemy wskaźnik pliku. 56 00:02:59,080 --> 00:03:03,140 Funkcja, która zwraca ten wskaźnik, fopen, pobiera dwa argumenty. 57 00:03:03,140 --> 00:03:07,440 Pierwszy to nazwa pliku wraz z rozszerzeniem pliku, jeśli to właściwe. 58 00:03:07,440 --> 00:03:10,980 Przypomnijmy, że rozszerzenie pliku nie ma wpływu na plik na najniższym poziomie. 59 00:03:10,980 --> 00:03:14,640 Mamy zawsze do czynienia z długą sekwencję zer i jedynek. 60 00:03:14,640 --> 00:03:19,630 Ale ma wpływ na to jak pliki są interpretowane i jakie aplikacje są wykorzystywane do ich otwierania. 61 00:03:19,630 --> 00:03:22,290 Drugi argument funkcji fopen jest jedna litera 62 00:03:22,290 --> 00:03:25,300 , która stoi za to, co mamy zamiar robić po to otwieramy plik. 63 00:03:25,300 --> 00:03:30,630 Istnieją trzy opcje dla tego argumentu - W, R, A. 64 00:03:30,630 --> 00:03:34,900 Wybraliśmy W w tym przypadku, ponieważ chcemy zapisać do pliku. 65 00:03:34,900 --> 00:03:38,820 R, jak można się domyślić, jest do odczytu w pliku. 66 00:03:38,820 --> 00:03:41,760 I jest dodanie do pliku. 67 00:03:41,760 --> 00:03:44,960 Chociaż zarówno w i mogą być stosowane do zapisu plików 68 00:03:44,960 --> 00:03:47,460 W rozpocznie pisania z początku pliku 69 00:03:47,460 --> 00:03:50,810 i potencjalnie zastąpić wszystkie dane, które zostały wcześniej zapisane. 70 00:03:50,810 --> 00:03:54,070 Domyślnie plik możemy otworzyć, jeśli nie istnieje, 71 00:03:54,070 --> 00:03:57,180 tworzona jest w naszym obecnym katalogu. 72 00:03:57,180 --> 00:04:00,540 Jednakże, jeśli chcemy uzyskać dostęp lub utworzyć plik w innym miejscu, 73 00:04:00,540 --> 00:04:02,650 w pierwszym argumencie fopen, 74 00:04:02,650 --> 00:04:05,840 możemy określić ścieżkę do pliku, w dodatku do nazwy pliku. 75 00:04:05,840 --> 00:04:09,490 A pierwsza część tego procesu jest tylko jedna linia kodu długi 76 00:04:09,490 --> 00:04:12,350 zawsze jest dobrą praktyką jest inny zestaw wierszy 77 00:04:12,350 --> 00:04:15,930 że sprawdzić, czy plik został pomyślnie otwarty lub utworzony. 78 00:04:15,930 --> 00:04:20,300 Jeśli fopen zwraca wartość NULL, nie chcemy, aby posunąć się naprzód z naszego programu, 79 00:04:20,300 --> 00:04:23,270 a to może się zdarzyć, jeśli system operacyjny to z pamięci 80 00:04:23,270 --> 00:04:27,940 lub jeśli spróbujesz otworzyć plik w katalogu, dla których nie mają odpowiednich uprawnień. 81 00:04:27,940 --> 00:04:31,780 >> Druga część procesu odbywa się w maszyny do pisania pętli. 82 00:04:31,780 --> 00:04:35,000 Używamy CS50 funkcji biblioteki, aby uzyskać danych od użytkownika, 83 00:04:35,000 --> 00:04:37,190 i przy założeniu, że nie chcą, aby zakończyć program, 84 00:04:37,190 --> 00:04:41,940 używamy funkcji fputs podjąć ciąg i zapisać go do pliku. 85 00:04:41,940 --> 00:04:46,700 fputs jest tylko jedną z wielu funkcji możemy użyć zapisu do pliku. 86 00:04:46,700 --> 00:04:51,920 Inne obejmują fwrite, fputc, a nawet fprintf. 87 00:04:51,920 --> 00:04:54,840 Niezależnie od tego, w szczególności funkcji skończymy stosując jednak 88 00:04:54,840 --> 00:04:57,480 wszyscy muszą wiedzieć, za pośrednictwem swoich argumentów, 89 00:04:57,480 --> 00:04:59,670 przynajmniej dwie - 90 00:04:59,670 --> 00:05:03,140 co powinno być napisane i gdzie musi być napisana na. 91 00:05:03,140 --> 00:05:07,240 W naszym przypadku wejście jest łańcuch, który musi być napisany 92 00:05:07,240 --> 00:05:11,290 i fp jest wskaźnik, który kieruje nas do miejsca, gdzie piszemy. 93 00:05:11,290 --> 00:05:15,330 W tym programie, druga część procesu jest raczej proste. 94 00:05:15,330 --> 00:05:17,360 Jesteśmy po prostu biorąc ciąg od użytkownika 95 00:05:17,360 --> 00:05:22,120 i dodając go bezpośrednio do naszego pliku z mało-to-nie walidacji wejścia lub kontroli bezpieczeństwa. 96 00:05:22,120 --> 00:05:26,160 Często jednak druga część odbędzie się na większą część swojego kodu. 97 00:05:26,160 --> 00:05:30,580 Wreszcie część trzecia jest na linii 58, gdzie zamknij plik. 98 00:05:30,580 --> 00:05:34,860 Tutaj nazywamy fclose i przekazać nasz oryginalny wskaźnik pliku. 99 00:05:34,860 --> 00:05:39,500 W następnej linii, zwracamy zero oznaczało koniec naszego programu. 100 00:05:39,500 --> 00:05:42,630 I tak, część trzecia jest tak proste. 101 00:05:42,630 --> 00:05:45,260 >> Przejdźmy do czytania z plików. 102 00:05:45,260 --> 00:05:48,220 Powrót w naszym katalogu mamy plik o nazwie printer.c. 103 00:05:48,220 --> 00:05:50,910 Przyjrzyjmy się jej z pliku stworzonego właśnie - 104 00:05:50,910 --> 00:05:53,350 Doc.txt. 105 00:05:53,350 --> 00:05:58,150 Program ten, jak nazwa wskazuje, będzie po prostu wydrukować zawartość pliku przekazany do niej. 106 00:05:58,150 --> 00:06:00,230 I tam mamy. 107 00:06:00,230 --> 00:06:03,780 Linie kodu mieliśmy wpisane wcześniej i zapisane w Doc.txt. 108 00:06:03,780 --> 00:06:06,980 Hi. Nazywam się Jason. 109 00:06:06,980 --> 00:06:09,120 Jeśli zagłębimy się printer.c, 110 00:06:09,120 --> 00:06:13,570 widzimy, że większość kodu wygląda podobnie do tego, co po prostu szliśmy przez w typewriter.c. 111 00:06:13,570 --> 00:06:16,720 Rzeczywiście linia 22, gdzie otworzył plik, 112 00:06:16,720 --> 00:06:19,220 i linii 39, gdzie zamknięty plik, 113 00:06:19,220 --> 00:06:23,890 oba niemal identyczne typewriter.c, z wyjątkiem fopen drugi argument. 114 00:06:23,890 --> 00:06:26,510 Tym razem mamy do odczytu z pliku, 115 00:06:26,510 --> 00:06:29,040 więc wybraliśmy R zamiast w. 116 00:06:29,040 --> 00:06:31,950 Tak więc, skupmy na drugiej części procesu. 117 00:06:31,950 --> 00:06:36,060 W linii 35, jak w drugim stanie naszego 4 pętli 118 00:06:36,060 --> 00:06:38,590 możemy wykonać połączenie do fgets, 119 00:06:38,590 --> 00:06:42,190 Funkcja towarzysz fputs sprzed. 120 00:06:42,190 --> 00:06:44,660 Tym razem mamy trzy argumenty. 121 00:06:44,660 --> 00:06:48,810 Pierwszy to wskaźnik do tablicy znaków gdzie ciąg zostanie zapisany. 122 00:06:48,810 --> 00:06:52,670 Drugi jest maksymalna liczba znaków do odczytu. 123 00:06:52,670 --> 00:06:56,010 A trzeci jest wskaźnik do pliku, z którymi pracujemy. 124 00:06:56,010 --> 00:07:00,780 Można zauważyć, że dla pętli kończy się, gdy fgets zwraca null. 125 00:07:00,780 --> 00:07:02,940 Istnieją dwa powodu, że może mieć miejsce. 126 00:07:02,940 --> 00:07:05,380 Po pierwsze, mógł wystąpić błąd. 127 00:07:05,380 --> 00:07:10,740 Po drugie, i co bardziej prawdopodobne, koniec pliku został osiągnięty i kolejne znaki nie były odczytywane. 128 00:07:10,740 --> 00:07:14,040 W przypadku, gdy zastanawiasz się, istnieją dwie funkcje, które pozwalają nam powiedzieć 129 00:07:14,040 --> 00:07:17,160 dlatego jest przyczyną tego konkretnego wskaźnika zerowego. 130 00:07:17,160 --> 00:07:21,090 I nic dziwnego, gdyż mamy do czynienia z pracy z plikami, 131 00:07:21,090 --> 00:07:26,940 zarówno ferror funkcja i funkcja start feof z literą F. 132 00:07:26,940 --> 00:07:32,130 >> Wreszcie, przed stwierdzić, jedna krótka notatka o zakończeniu funkcji pliku, 133 00:07:32,130 --> 00:07:36,690 , które, jak już wspomniano, jest napisane jak feof. 134 00:07:36,690 --> 00:07:41,550 Często znajdziesz się przy użyciu while i pętli do stopniowego zapoznania się przez pliki. 135 00:07:41,550 --> 00:07:45,790 Tak więc, trzeba mieć sposób na zakończenie te pętle po dojdziesz do końca z tych plików. 136 00:07:45,790 --> 00:07:50,510 Wywołanie feof na wskaźnika pliku i sprawdzamy, czy to prawda 137 00:07:50,510 --> 00:07:52,310 będzie nie tylko to. 138 00:07:52,310 --> 00:07:59,820 Tak więc, podczas gdy pętla z warunkiem (! Feof (fp)) może wydawać się rozwiązaniem idealnie odpowiedni. 139 00:07:59,820 --> 00:08:03,770 Jednak, że mamy jedną linię w lewo, w naszym pliku tekstowym. 140 00:08:03,770 --> 00:08:07,130 Będziemy wejść na naszą pętlę while i wszystko ułoży się zgodnie z planem. 141 00:08:07,130 --> 00:08:12,750 Na następnej rundzie przez nasz program będzie sprawdzić czy feof z fp jest prawdziwe, 142 00:08:12,750 --> 00:08:15,430 ale - i to jest kluczowy punkt do zrozumienia tutaj - 143 00:08:15,430 --> 00:08:17,770 to nie będzie prawda jeszcze. 144 00:08:17,770 --> 00:08:21,110 To dlatego, że celem nie jest feof sprawdzić 145 00:08:21,110 --> 00:08:24,400 jeśli następne wywołanie funkcji read trafi na koniec pliku, 146 00:08:24,400 --> 00:08:28,190 lecz sprawdzić, czy koniec pliku został osiągnięty. 147 00:08:28,190 --> 00:08:30,140 W przypadku tego przykładu 148 00:08:30,140 --> 00:08:32,780 czytając ostatnią linię naszego pliku idzie idealnie gładko, 149 00:08:32,780 --> 00:08:36,210 ale program nie wie jeszcze, że został trafiony koniec naszego pliku. 150 00:08:36,210 --> 00:08:40,549 To nie jest aż robi jedną dodatkową lekturę, że liczniki na koniec pliku. 151 00:08:40,549 --> 00:08:43,210 Dlatego prawidłowy stan byłyby następujące: 152 00:08:43,210 --> 00:08:49,330 fgets i jej trzy argumenty - wyjście, wielkość produkcji i FP - 153 00:08:49,330 --> 00:08:52,570 i wszystko to nie jest równa null. 154 00:08:52,570 --> 00:08:55,260 Jest to podejście wzięliśmy printer.c, 155 00:08:55,260 --> 00:08:57,890 w tym przypadku, po wyjściu pętli, 156 00:08:57,890 --> 00:09:04,290 można nazwać feof lub ferror poinformować użytkownika co do konkretnego uzasadnienia dla zamykania tej pętli. 157 00:09:04,290 --> 00:09:08,100 >> Zapis do i odczyt z pliku jest w jego najbardziej podstawowym, 158 00:09:08,100 --> 00:09:10,150 prosty 3-częściowy proces. 159 00:09:10,150 --> 00:09:12,530 Po pierwsze, musimy otworzyć plik. 160 00:09:12,530 --> 00:09:16,740 Po drugie, musimy umieścić kilka rzeczy do naszego pliku lub wybrać kilka rzeczy z niego. 161 00:09:16,740 --> 00:09:19,200 Po trzecie, zamknij plik. 162 00:09:19,200 --> 00:09:21,170 Pierwszy i ostatni części są proste. 163 00:09:21,170 --> 00:09:23,920 W środkowej części, gdzie jest trudne rzeczy leży. 164 00:09:23,920 --> 00:09:27,760 I chociaż pod maską mamy zawsze do czynienia z długą sekwencję zer i jedynek, 165 00:09:27,760 --> 00:09:30,710 to nie pomaga podczas kodowania, aby dodać warstwę abstrakcji 166 00:09:30,710 --> 00:09:35,350 który włącza sekwencję w coś bardziej przypomina to, co jesteśmy przyzwyczajeni do zobaczenia. 167 00:09:35,350 --> 00:09:39,570 Na przykład, jeśli pracujemy z 24-bitowego pliku bitmapy 168 00:09:39,570 --> 00:09:43,290 będziemy prawdopodobnie czytanie lub pisanie trzy bajty na raz. 169 00:09:43,290 --> 00:09:46,450 W takim przypadku, warto byłoby określić i odpowiednio nazwać 170 00:09:46,450 --> 00:09:48,980 struct to 3 bajty duże. 171 00:09:48,980 --> 00:09:51,410 >> Choć praca z plikami może wydawać się skomplikowane, 172 00:09:51,410 --> 00:09:54,530 ich stosowania pozwala nam zrobić coś naprawdę niezwykłego. 173 00:09:54,530 --> 00:09:58,880 Możemy zmienić stan świata poza naszym programie 174 00:09:58,880 --> 00:10:01,730 możemy stworzyć coś, co żyje poza życia naszego programu, 175 00:10:01,730 --> 00:10:07,190 lub może nawet coś zmienić, który został utworzony przed nasz program uruchomić. 176 00:10:07,190 --> 00:10:11,210 Interakcja z plików jest naprawdę potężny częścią programowania w C. 177 00:10:11,210 --> 00:10:15,300 i jestem podekscytowany, aby zobaczyć, co masz zamiar stworzyć z nim w kodzie przyjść. 178 00:10:15,300 --> 00:10:19,770 Nazywam się Jason Hirschhorn. To CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [Śmiech] 181 00:10:25,940 --> 00:10:29,330 Okay. One podjąć. Jedziemy. 182 00:10:49,000 --> 00:10:52,140 Kiedy myślimy o pliku - >> Och, czekaj. Przepraszam. 183 00:10:52,140 --> 00:10:56,800 [Śmiech] Okay. 184 00:11:06,620 --> 00:11:09,970 Cześć. 185 00:11:13,670 --> 00:11:16,310 Kiedy myślimy o pliku - 186 00:11:17,610 --> 00:11:20,710 Kiedy myślisz o pliku - Okay. Powiedz mi, kiedy będziesz gotowy. 187 00:11:20,710 --> 00:11:22,520 Świetnie. 188 00:11:22,520 --> 00:11:26,180 Choć czytanie z teleprompter może wydawać - nie. My bad.