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 [Джейсон Хиршхорн, Гарвардский университет] 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 Хотя чтение с телесуфлера может показаться - нет. Мое плохое.