1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [Файл I / O] 2 00:00:02,000 --> 00:00:04,000 [Джейсон Хіршхорн, Гарвардський університет] 3 00:00:04,000 --> 00:00:07,000 [Це CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 Коли ми думаємо про файл, що приходить на розум це документ Microsoft Word, 5 00:00:11,000 --> 00:00:14,000 зображень JPEG, MP3 або пісню, 6 00:00:14,000 --> 00:00:17,000 і ми взаємодіємо з кожним з цих типів файлів різними способами. 7 00:00:17,000 --> 00:00:20,000 Наприклад, у документі Word ми додамо текст 8 00:00:20,000 --> 00:00:24,000 в той час як з зображенням JPEG ми могли б обрізати краю або відретушувати кольору. 9 00:00:24,000 --> 00:00:28,000 Тим не менше, під капотом всі файли в нашому комп'ютері є не більше 10 00:00:28,000 --> 00:00:31,000 ніж довга послідовність нулів і одиниць. 11 00:00:31,000 --> 00:00:33,000 Це залежить від конкретного додатка, яке взаємодіє з файлом 12 00:00:33,000 --> 00:00:38,000 щоб вирішити, як обробити цю довгу послідовність і представити його користувачеві. 13 00:00:38,000 --> 00:00:41,000 З одного боку, документ може дивитися тільки на один байт, 14 00:00:41,000 --> 00:00:45,000 або 8 нулів і одиниць, а також відображати ASCII символів на екрані. 15 00:00:45,000 --> 00:00:48,000 З іншого боку, растрові зображення можуть дивитися на 3 байти, 16 00:00:48,000 --> 00:00:50,000 або 24 нулів і одиниць, 17 00:00:50,000 --> 00:00:53,000 і інтерпретувати їх як 3 шістнадцяткових чисел 18 00:00:53,000 --> 00:00:56,000 , Які представляють значення для червоного, зеленого і синього 19 00:00:56,000 --> 00:00:58,000 В один піксель зображення. 20 00:00:58,000 --> 00:01:01,000 Все, що вони можуть виглядати на екрані, по суті своїй, 21 00:01:01,000 --> 00:01:05,000 Файли є не більш ніж послідовність з нулів і одиниць. 22 00:01:05,000 --> 00:01:08,000 Так що давайте пірнати і дивитися на те, як ми насправді маніпулювати цими нулями і одиницями 23 00:01:08,000 --> 00:01:12,000 коли справа доходить до запису та читання з файлу. 24 00:01:12,000 --> 00:01:15,000 >> Я почну розбити його на прості 3-частина процесу. 25 00:01:15,000 --> 00:01:19,000 Далі, я буду пірнати на дві приклади коду, що демонструють ці три частини. 26 00:01:19,000 --> 00:01:23,000 Нарешті, я розгляну процес і деякі з його найбільш важливі деталі. 27 00:01:23,000 --> 00:01:25,000 Як і з будь-який файл, який знаходиться на робочому столі, 28 00:01:25,000 --> 00:01:28,000 Перше, що потрібно зробити, це відкрити його. 29 00:01:28,000 --> 00:01:31,000 У C ми робимо це, оголосивши покажчик на зумовлені структури 30 00:01:31,000 --> 00:01:33,000 , Що являє собою файл на диску. 31 00:01:33,000 --> 00:01:38,460 У цьому виклику функції, ми також вирішити, чи хочемо ми писати або читати з файлу. 32 00:01:38,460 --> 00:01:41,660 Далі, ми робимо фактично читання і запису. 33 00:01:41,660 --> 00:01:44,800 Є цілий ряд спеціалізованих функцій, ми можемо використовувати в цій частині, 34 00:01:44,800 --> 00:01:48,790 і майже всі вони починаються з літери F, яка виступає за файл. 35 00:01:48,790 --> 00:01:53,560 Останнє, схоже на маленький червоний хрестик у правому верхньому куті відкритих файлів на вашому комп'ютері, 36 00:01:53,560 --> 00:01:56,680 ми закриваємо файл з остаточним виклику функції. 37 00:01:56,680 --> 00:01:59,540 Тепер у нас є загальне уявлення про те, що ми збираємося робити, 38 00:01:59,540 --> 00:02:02,000 Давайте поринемо в код. 39 00:02:02,000 --> 00:02:06,100 >> У цьому каталозі ми маємо два C файли і їх відповідні виконувані файли. 40 00:02:06,100 --> 00:02:09,710 Машинки програма займає одне аргумент командного рядка, 41 00:02:09,710 --> 00:02:12,060 Назва документа ми хочемо створити. 42 00:02:12,060 --> 00:02:16,160 У цьому випадку, ми будемо називати його doc.txt. 43 00:02:16,160 --> 00:02:19,080 Давайте запустимо програму і введіть пару рядків. 44 00:02:19,080 --> 00:02:23,660 Привіт. Мене звуть Джейсон. 45 00:02:23,660 --> 00:02:26,710 Нарешті, ми типу "кинути". 46 00:02:26,710 --> 00:02:29,720 Якщо ми зараз перерахуємо всі файли в цьому каталогі, 47 00:02:29,720 --> 00:02:33,770 ми бачимо, що новий документ існує називають doc.txt. 48 00:02:34,190 --> 00:02:36,110 Це файл цієї програми тільки що створили. 49 00:02:36,110 --> 00:02:40,520 І, звичайно, це теж не більше, ніж довга послідовність нулів і одиниць. 50 00:02:41,100 --> 00:02:43,260 Якщо ми відкриємо цей новий файл, 51 00:02:43,260 --> 00:02:45,870 ми бачимо 3 рядки коду ми увійшли в нашу програму - 52 00:02:46,060 --> 00:02:49,060 Привіт. Травень ім'я Джейсон. 53 00:02:49,580 --> 00:02:52,090 Але те, що відбувається насправді, коли typewriter.c працює? 54 00:02:52,810 --> 00:02:55,520 У першому рядку інтерес для нас є лінією 24. 55 00:02:55,560 --> 00:02:58,490 У відповідності з цим ми заявляємо про нашу покажчика файлу. 56 00:02:59,080 --> 00:03:03,140 Функція, яка повертає цей покажчик, Еореп, приймає два аргументи. 57 00:03:03,140 --> 00:03:07,440 Перше ім'я файлу включаючи розширення файлу, якщо необхідно. 58 00:03:07,440 --> 00:03:10,980 Нагадаємо, що розширення файлу не впливає на файл на найнижчому рівні. 59 00:03:10,980 --> 00:03:14,640 Ми завжди маємо справу з довгої послідовності нулів та одиниць. 60 00:03:14,640 --> 00:03:19,630 Але цей вплив, як файли інтерпретуються і які програми використовуються, щоб відкрити їх. 61 00:03:19,630 --> 00:03:22,290 Другий аргумент Еореп є однієї букви 62 00:03:22,290 --> 00:03:25,300 що стоїть за те, що ми плануємо зробити після відкриття файлу. 63 00:03:25,300 --> 00:03:30,630 Є три варіанти для цього аргументу - W, R, і А. 64 00:03:30,630 --> 00:03:34,900 Ми вибрали W в цьому випадку, тому що ми хочемо записати у файл. 65 00:03:34,900 --> 00:03:38,820 R, як ви можете здогадатися, призначений для читання в файл. 66 00:03:38,820 --> 00:03:41,760 А для додавання до файлу. 67 00:03:41,760 --> 00:03:44,960 У той час як вага і може бути використаний для запису файлів, 68 00:03:44,960 --> 00:03:47,460 W почнемо писати від початку файлу 69 00:03:47,460 --> 00:03:50,810 і потенційно перезаписати всі дані, які раніше були збережені. 70 00:03:50,810 --> 00:03:54,070 За замовчуванням, ми відкриваємо файл, якщо він ще не існує, 71 00:03:54,070 --> 00:03:57,180 створюється в нашому нинішньому робочому каталозі. 72 00:03:57,180 --> 00:04:00,540 Однак, якщо ми хочемо отримати доступ або створити файл в іншому місці, 73 00:04:00,540 --> 00:04:02,650 У перший аргумент Еореп, 74 00:04:02,650 --> 00:04:05,840 ми можемо вказати шлях до файлу, на додаток до імені файлу. 75 00:04:05,840 --> 00:04:09,490 У той час як перша частина цього процесу є тільки одного рядка коду довжиною, 76 00:04:09,490 --> 00:04:12,350 це завжди гарна практика, щоб включити інший набір ліній 77 00:04:12,350 --> 00:04:15,930 що переконаєтеся, що файл був успішно відкритий або створений. 78 00:04:15,930 --> 00:04:20,300 Якщо Еореп повертає нуль, ми не хотіли б просуватися вперед з нашою програмою, 79 00:04:20,300 --> 00:04:23,270 і це може відбутися, якщо операційна система не вистачає пам'яті 80 00:04:23,270 --> 00:04:27,940 або, якщо ми спробуємо відкрити файл у каталог, для якого у нас не було відповідних дозволів. 81 00:04:27,940 --> 00:04:31,780 >> Друга частина процесу проходить в той час як цикл друкарської машинки. 82 00:04:31,780 --> 00:04:35,000 Ми використовуємо CS50 бібліотечні функції для отримання даних від користувача, 83 00:04:35,000 --> 00:04:37,190 і припускаючи, що вони не хочуть, щоб вийти з програми, 84 00:04:37,190 --> 00:04:41,940 ми використовуємо функцію fputs взяти рядок і записати її у файл. 85 00:04:41,940 --> 00:04:46,700 fputs є лише однією з багатьох функцій ми могли б використовувати для запису у файл. 86 00:04:46,700 --> 00:04:51,920 Інші включають FWRITE, fputc, і навіть Fprintf. 87 00:04:51,920 --> 00:04:54,840 Незалежно від конкретної функції, ми в кінцевому підсумку, використовуючи, однак, 88 00:04:54,840 --> 00:04:57,480 всі вони повинні знати, через свої аргументи, 89 00:04:57,480 --> 00:04:59,670 принаймні, дві речі - 90 00:04:59,670 --> 00:05:03,140 що має бути написано і де воно має бути записано. 91 00:05:03,140 --> 00:05:07,240 У нашому випадку, вхід рядок, яка повинна бути записана 92 00:05:07,240 --> 00:05:11,290 і FP є покажчиком, який спрямовує нас туди, де ми пишемо. 93 00:05:11,290 --> 00:05:15,330 У цій програмі, частиною другою процес досить простий. 94 00:05:15,330 --> 00:05:17,360 Ми просто приймає рядок від користувача 95 00:05:17,360 --> 00:05:22,120 і додавши його безпосередньо в наш файл з невеликим до перевірки не вхід або перевірок безпеки. 96 00:05:22,120 --> 00:05:26,160 Часто, однак, друга частина буде займати велику частину вашого коду. 97 00:05:26,160 --> 00:05:30,580 І, нарешті, третя частина знаходиться на лінії 58, де ми закриваємо файл. 98 00:05:30,580 --> 00:05:34,860 Тут ми називаємо Fclose і передати його нашим оригінальний покажчик файлу. 99 00:05:34,860 --> 00:05:39,500 У наступні лінії, ми повертаємося нулю, що свідчить про кінець нашої програми. 100 00:05:39,500 --> 00:05:42,630 І, так, третя частина так само просто, як це. 101 00:05:42,630 --> 00:05:45,260 >> Давайте перейдемо до читання з файлів. 102 00:05:45,260 --> 00:05:48,220 Повернутися в нашому каталозі у нас є файл з ім'ям printer.c. 103 00:05:48,220 --> 00:05:50,910 Давайте запустимо його з файлу, який ми тільки що створили - 104 00:05:50,910 --> 00:05:53,350 doc.txt. 105 00:05:53,350 --> 00:05:58,150 Ця програма, як випливає з назви, буде просто роздрукувати вміст файлу передається йому. 106 00:05:58,150 --> 00:06:00,230 І у нас це є. 107 00:06:00,230 --> 00:06:03,780 Рядків коду ми ввели раніше і зберігається в doc.txt. 108 00:06:03,780 --> 00:06:06,980 Привіт. Мене звуть Джейсон. 109 00:06:06,980 --> 00:06:09,120 Якщо ми заглибимося в printer.c, 110 00:06:09,120 --> 00:06:13,570 ми бачимо, що багато коду схоже на те, що ми просто йшли через в typewriter.c. 111 00:06:13,570 --> 00:06:16,720 Дійсно лінії 22, де ми відкрили файл, 112 00:06:16,720 --> 00:06:19,220 і лінія 39, де ми закрили файл, 113 00:06:19,220 --> 00:06:23,890 обидва майже ідентичні typewriter.c, за винятком Еореп другий аргумент. 114 00:06:23,890 --> 00:06:26,510 На цей раз ми читаємо з файлу, 115 00:06:26,510 --> 00:06:29,040 таким чином, ми вибрали г замість ш. 116 00:06:29,040 --> 00:06:31,950 Таким чином, давайте зосередимося на другу частину цього процесу. 117 00:06:31,950 --> 00:06:36,060 У рядку 35, а друга умова в нашому 4 петлі, 118 00:06:36,060 --> 00:06:38,590 ми робимо виклик ЕдеЬз, 119 00:06:38,590 --> 00:06:42,190 компаньйоном функції fputs, ніж раніше. 120 00:06:42,190 --> 00:06:44,660 На цей раз у нас є три аргументи. 121 00:06:44,660 --> 00:06:48,810 Першим з них є покажчиком на масив символів, де рядок буде збережена. 122 00:06:48,810 --> 00:06:52,670 По-друге, це максимальне число символів для читання. 123 00:06:52,670 --> 00:06:56,010 І, по-третє, покажчик на файл, з яким ми працюємо. 124 00:06:56,010 --> 00:07:00,780 Ви помітите, що цикл закінчується, коли ЕдеЬз повертає нульове значення. 125 00:07:00,780 --> 00:07:02,940 Є дві причини, що це може трапитися. 126 00:07:02,940 --> 00:07:05,380 По-перше, сталася помилка. 127 00:07:05,380 --> 00:07:10,740 По-друге, і це більш вірогідно, кінець файлу був досягнутий, і не більше символів читали. 128 00:07:10,740 --> 00:07:14,040 У випадку, якщо Ви ставите питанням, дві функції дійсно існують, що дозволяє нам говорити 129 00:07:14,040 --> 00:07:17,160 Причина яка є причиною для даного покажчика NULL. 130 00:07:17,160 --> 00:07:21,090 І не дивно, так як вони мають відношення до роботи з файлами, 131 00:07:21,090 --> 00:07:26,940 як FERROR функції та розпочала feof функції з буквою F. 132 00:07:26,940 --> 00:07:32,130 >> Нарешті, перш ніж ми укладаємо, одне невелике зауваження про кінець файлу функції, 133 00:07:32,130 --> 00:07:36,690 , Який, як тільки що говорилося, записується у вигляді feof. 134 00:07:36,690 --> 00:07:41,550 Часто ви будете використовувати час і для петлі поступово читав ваш шлях через файли. 135 00:07:41,550 --> 00:07:45,790 Таким чином, ви будете потребувати шлях до припинення цих петель після того, як ви дійдете до кінця цих файлів. 136 00:07:45,790 --> 00:07:50,510 Виклик feof на покажчик файлу і перевірки, щоб побачити, якщо це правда 137 00:07:50,510 --> 00:07:52,310 б зробити саме це. 138 00:07:52,310 --> 00:07:59,820 Таким чином, у той час як цикл з умовою (! Feof (FP)) може здатися цілком відповідним рішенням. 139 00:07:59,820 --> 00:08:03,770 Тим не менш, у нас є одна лінія залишається в наших текстових файлів. 140 00:08:03,770 --> 00:08:07,130 Ми будемо вводити наші в той час як петлі і все буде працювати так, як планувалося. 141 00:08:07,130 --> 00:08:12,750 На наступний раунд до кінця, наша програма буде перевіряти, якщо feof ПС, правда, 142 00:08:12,750 --> 00:08:15,430 але - і це ключовий момент для розуміння тут - 143 00:08:15,430 --> 00:08:17,770 це не буде істинним тільки поки. 144 00:08:17,770 --> 00:08:21,110 Це тому, що мета feof не перевірити 145 00:08:21,110 --> 00:08:24,400 якщо при наступному виклику функція читання потрапить в кінець файлу, 146 00:08:24,400 --> 00:08:28,190 а перевірити, чи є чи ні кінець файлу вже досягнута. 147 00:08:28,190 --> 00:08:30,140 У даному прикладі, 148 00:08:30,140 --> 00:08:32,780 читання останньому рядку нашого файлу йде ідеально рівно, 149 00:08:32,780 --> 00:08:36,210 але програма ще не знає, що ми потрапили в кінці нашого файлу. 150 00:08:36,210 --> 00:08:40,549 Це не поки він не один додатковий прочитав, що це лічильники кінці файлу. 151 00:08:40,549 --> 00:08:43,210 Таким чином, правильне умова може бути наступним: 152 00:08:43,210 --> 00:08:49,330 ЕдеЬз і трьох аргументів - вихід, розмір вихідної і FP - 153 00:08:49,330 --> 00:08:52,570 і все, що не дорівнює нулю. 154 00:08:52,570 --> 00:08:55,260 Це підхід, який ми взяли в printer.c, 155 00:08:55,260 --> 00:08:57,890 і в цьому випадку, після циклу виходить, 156 00:08:57,890 --> 00:09:04,290 Ви могли б назвати feof або FERROR повідомити користувачеві, як до конкретної аргументації для виходу з цього циклу. 157 00:09:04,290 --> 00:09:08,100 >> Запис і читання з файлу, на самому базовому, 158 00:09:08,100 --> 00:09:10,150 Простий 3-частина процесу. 159 00:09:10,150 --> 00:09:12,530 По-перше, ми відкриваємо файл. 160 00:09:12,530 --> 00:09:16,740 По-друге, ми ставимо деякі речі в нашій файл або прийняти деякі речі з нього. 161 00:09:16,740 --> 00:09:19,200 По-третє, ми закриваємо файл. 162 00:09:19,200 --> 00:09:21,170 Перша і остання частини легко. 163 00:09:21,170 --> 00:09:23,920 У середній частині, де лежить складний матеріал. 164 00:09:23,920 --> 00:09:27,760 І хоча під капотом ми завжди маємо справу з довгої послідовності нулів та одиниць, 165 00:09:27,760 --> 00:09:30,710 воно допомагає при кодуванні, щоб додати шар абстракції 166 00:09:30,710 --> 00:09:35,350 Виходить, що послідовність у те, що більше нагадує те, що ми звикли бачити. 167 00:09:35,350 --> 00:09:39,570 Наприклад, якщо ми працюємо з 24-бітної растровий файл, 168 00:09:39,570 --> 00:09:43,290 ми, ймовірно, буде читати або писати три байти за один раз. 169 00:09:43,290 --> 00:09:46,450 У такому випадку, це мало б сенс, щоб визначити і відповідним чином назвати 170 00:09:46,450 --> 00:09:48,980 структуру, яка складає 3 байти великий. 171 00:09:48,980 --> 00:09:51,410 >> Хоча робота з файлами може здатися складним, 172 00:09:51,410 --> 00:09:54,530 використання їх дозволяє нам зробити щось дійсно чудове. 173 00:09:54,530 --> 00:09:58,880 Ми можемо змінити стан світу за межами нашій програмі, 174 00:09:58,880 --> 00:10:01,730 ми можемо створити те, що живе за життя нашої програми, 175 00:10:01,730 --> 00:10:07,190 або ми можемо навіть змінити те, що було створено до нашої програмі почали працювати. 176 00:10:07,190 --> 00:10:11,210 Взаємодія з файлами це дійсно потужна частина програмування мовою C. 177 00:10:11,210 --> 00:10:15,300 і я радий бачити, що ви збираєтеся створити з ним в коді, щоб прибути. 178 00:10:15,300 --> 00:10:19,770 Мене звуть Джейсон Хіршхорн. Це CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [Сміх] 181 00:10:25,940 --> 00:10:29,330 Добре. Один прийняти. Тут ми йдемо. 182 00:10:49,000 --> 00:10:52,140 Коли ми думаємо про файл - >> Ой, зачекайте. Вибачте. 183 00:10:52,140 --> 00:10:56,800 [Сміх] Добре. 184 00:11:06,620 --> 00:11:09,970 Ей там. 185 00:11:13,670 --> 00:11:16,310 Коли ми думаємо про файл - 186 00:11:17,610 --> 00:11:20,710 Коли ви думаєте про файл - Добре. Скажіть, коли ви будете готові. 187 00:11:20,710 --> 00:11:22,520 О, відмінно. 188 00:11:22,520 --> 00:11:26,180 Хоча читання з телесуфлера може здатися - немає. Моє погане.