Этапы проектирование программного обеспечения (ПО) 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Этапы проектирование программного обеспечения (ПО)



При структурном подходе.

Программное средство (ПС) – это совокупность программ определенного назначения, пригодных для исполнения на ЭВМ. Отдельная программа может быть как частью существующего ПС, так и самостоятельным ПС.

Программист должен создавать правильно, корректно работающие программы.

Правильность или корректность – это свойство соответствия проверяемого объекта некоторому эталонному объекту или совокупности формализованных эталонных характеристик и правил. Корректность программы при проектировании наиболее полно определяется степенью соответствия предъявляемым к ней формализованным требованиям – программной спецификации.

Рассмотрим задание на написание программы, принимающей в качестве аргументов запуска простое арифметическое выражение, состоящее из двух операндов в формате с плавающей точкой и знака математической операции, стоящей между ними. Операнды должны быть разделены пробельными символами. Программа должна реализовывать инфиксный калькулятор, вычисление значения выражения вида "операнд_1 операция опернд_2". В данном случае корректность работы программы подразумевает получение правильного результата вычисления математического выражения и, возможно, выдачу сообщений об ошибке в случае передаче программе неверных параметров. После вывода результата в стандартный поток вывода программа должна завершить свою работу. Предположим, что созданный исполняемый модуль будет именован CALC.EXE, в этом случае запуск программы из командной строки

"C:\>CALC.EXE 4 + 5" [Enter] (на Microsoft-платформе),

"$./CALC 4 + 5" [Enter] (на Linux-платформе),

должен привести к выводу сообщения-результата, соответствующего значению 9, а запуск

"C:\>CALC.EXE 4 + 9 > RES.TXT" [Enter]

должен привести к созданию текстового файла, содержащего символ '9' и символ конца файла EOF.

При отсутствии полностью формализованной спецификации требований в качестве эталона, которому должна соответствовать программа и результата ее функционирования, иногда используются неформализованные представления разработчика, пользователя или заказчика программ. Однако понятие корректности программ по отношению к запросам пользователя или заказчика сопряжено с неопределенностью самого этого эталона, которому должна соответствовать программа. Вследствие этого понятие корректности программ становится субъективным и его невозможно определить количественно. Неопределенность программных спецификаций уменьшается в процессе разработки программ путем уточнения требований по согласованию между разработчиком и заказчиком.

Однако внешне правильная и корректно работающая программа может содержать в себе скрытые, трудно выявляемые ошибки, связанные с ошибками проектирования. В частности, в языке Си существует много так называемых узких мест, связанных с функциями обработки строк. Большинство программистов знает о возможных ошибках, связанных с передачей функции printf () строк - символьных массивов. По вине программиста переданная строка может не содержать так называемого нуль-терминатора, нулевого байта, символизирующего конец строки, что может привести к срыву стека исполняемой программы. Однако при дальнейшем анализе функций обработки строк мы видим целый куст проблем-ошибок, связанных с обработкой таких незавершенных строк. Даже базовая функция strlen () не страхует нас от получения неверного результат при передаче ей слишком длинных строк в случае если в ее реализации нет проверки состояния флага переполнения разрядной сетки.

Аналогичная ситуация связана с обработкой исключений в С ++. Если программист не реализует программные средства обработки исключений, за него эту работу выполняет среда исполнения его программ, однако наиболее часто заданная по умолчанию обработка исключений заключается в аварийном завершении работы программы с выдачей соответствующего сообщения.

В случае если ошибка в работе программы проявляется в ходе ее эксплуатации, то возможны два пути ее локализации:

1. ошибка в работе программы проявляется лишь при определенных, крайне редко используемых условиях, но исправление ее невозможно в силу сложности ПС, в этом случае ошибка документируется;

2. если это возможно, то ошибка в работе программы должна быть изучена и устранена.

Таким образом, микропроектирование ПО возлагает на программиста-разработчика ответственность за знание особенностей программно-аппаратной платформы. Именно поэтому необходимо осознанно формировать культуру программирования уже на начальном этапе обучения. Начинающий программист должен прочувствовать важность грамотной разработки даже малых программ, наличие четкой структуры приложения, ясно отражающей его спецификацию.

Рассмотрим жизненный цикл ПО, он включает в себя следующие основные этапы:

1) системный анализ, в ходе которого определяется потребность в ПО, его назначении и основных функциональных характеристиках, оцениваются затраты и возможная эффективность применения такого комплекса;

2) проектирование ПО, включающее в себя разработку структуры комплекса и его компонент, программирование модулей и ряд этапов отладки, а также испытание и внедрение для регулярной эксплуатации созданной версии ПО;

3) эксплуатацию ПО, заключающуюся в исполнении, функционировании программ на ЭВМ для обработки информации и получения результатов, являющихся целью создания ПО, а также в обеспечении достоверности и надежности выдаваемых данных;

4) сопровождение ПО, состоящее в эксплуатационном обслуживании, развитии функциональных возможностей и повышении эксплуатационных характеристик ПО, тиражировании и переносе ПО на различные виды вычислительных средств.

 

Следствием данного жизненного цикла ПО является каскадная схема разработки ПО, определяющая следующую последовательность действий:

1. постановка задачи;

2. анализ требований и определение спецификаций, примерно 40% времени, затрачиваемого на разработку ПО;

3. проектирование,40%;

4. реализация, 5%;

5. тестирование, 15%;

6. модификация.

Этапы со второго по пятый касаются непосредственно реализации ПО, шестой – процесса сопровождения ПО. Первый этап касается непосредственно разработки технического задания (ТЗ), являющегося для команды разработчиков основным документом, описывающим конечных результат их труда.

При циклической схеме разработки ПО происходит последовательное, циклическое повторение этих этапов. При возврате на первый этап происходит уточнение ТЗ, на этапе тестирования выявляются ошибки проектирования и реализации, которые в свою очередь влекут за собой внесение изменений в ТЗ и очередной проход по этапам проектирования и реализации.

При реализации относительно небольших программ, на этапе проектирования программист должен ответить на следующий ряд вопросов:

1. Что необходимо сделать?

2. Каким образом это необходимо сделать?

3. Почему именно так он должен сделать и каковы альтернативы?

4. Что произойдет, если он сделает именно так?

Исходя из вышеизложенного, на этапе проектирования начинающему программисту рекомендуется следующий сценарий работы:

1. Анализ задачи (задания к лабораторной работе).

2. Описание входного потока данных, например, аргументы, переданные программе через командную строку, текстовый файл и т.д. На данном этапе необходимо явно выделить ”первичный”1 и ”вторичный” потоки данных, если таковые имеются. Например, ”первичный” поток данных может передаваться программе при запуске, а вторичный поток данных определяется для программы при выполнении заложенного в нее алгоритма, набора инструкций.

3. Описание выходного потока данных, порождаемого программой, например, сообщение, выводимое на экран, или создаваемый текстовый файл, или значение, возвращаемое программой операционной системе при завершении работы. На данном этапе также явно выделить ”первичный”, основной, поток данных, порождаемый программно, и вторичный поток, например поток сообщений ошибок STDERR, либо поток диалогов с пользователем.

4. Составить схему, отображающую используемые программой информационные потоки и объекты, участвующие в организации информационного обмена с указанием условий, при которых данные потоки порождается.

5. Описание возможных, допускаемых программой "ошибок"2, правил, по которым выявляются "ошибки". Оформление описания данных ошибок как отдельного файла протокола, поставляемого с программой.

6. Описание правил обработки программой "ошибок", как во входном потоке, так и в выходном потоке данных. То есть если предыдущий этап рассматривать как описание того, что может случиться, то на данном этапе необходимо описать, как данные события-ошибки необходимо обрабатывать.

7. Описание этапов последовательного, пошагового выполнения программы. Выделение функциональных блоков и описание их в виде отдельных модулей, функций.

8. Описание пошагового сценария работы программы с организацией ветвления при реализации логики работы программы как в штатном, нормальном режиме работы, так и в случае обработки ошибок. Составление обобщенной блок схемы функционирования приложения.

9. Составить размеченный граф состояний, соответствующий пошаговой работе программы. Каждой вершине графа поставить в соответствие целочисленное значение.

10. Исходя из номеров вершин в графе, описывающем ПО, определить значения, возвращаемые функциями-модулями с учетом обработки ошибок и досрочного завершения работы программы.

11. Перейти от линейной структуры пошагового исполнения к циклической, а внутри цикла процедуру множественного выбора-ветвления.

 

Распишем процесс создания программы переименования фалов на основании данного сценария проектирования ПС.

Пункт 1.

Задание: разработать программу, принимающую через аргументы командной строки два имени файлов файл_1 и файл_2, разделенные пробелом, осуществляющую переименование-перенос файла_1 в файл_2. Программа должна поддерживать опцию получения справки и корректно отрабатывать попытку запуска с неправильными параметрами.

Изучив справочник по параметрам командной строки мы находим существующую программу-прототип RENAME, являющуюся исполняемым файлом. Вот содержимое встроенной справки о данной программе.

1.

2. RENAME

Изменение имени отдельного файла. Команда rename перечисленными ниже параметрами доступна только при использовании консоли восстановления. Команда rename другими параметрами доступна из командной строки.

rename [ диск: ][ путь ] имя_файла1 имя_файла2

-или-

ren [ диск: ][ путь ] имя_файла1 имя_файла2

Параметры

[ диск: ][ путь ] имя_файла1

Имя и размещение файла, который требуется переименовать. Использование подстановочных символов не допускается.

имя_файла2

Новое имя файла. При переименовании не могут быть заданы новый диск или каталог.

 

A. Примечания

  • Переименование файлов

Допускается переименование всех файлов, соответствующих заданному имени файла. Команду rename нельзя использовать для переименования файлов на разных дисках или для их перемещения в другой каталог.

  • Использование подстановочных знаков при переименовании

Подстановочные знаки (* и?) могут быть использованы в параметрах, задающих имена. Если они использованы в параметре имя_файла_2, то символы, замещаемые символами подстановки, будут теми же, что и в параметре имя_файла_1.

  • Команда переименования не будет работать, если имя_файла_2 уже существует.

Если имя файла, задаваемое параметром имя_файла_2, уже существует, команда rename выведет на экран следующее сообщение:

Дублирование имени файла или файл не найден

 

Пункт 2.

Первичный поток данных, обрабатываемых программой, представляет собой аргументы, переданные программе при запуске, аргументы функции main (). Вторичным, порождаемым под управлением первичного, потоком является поток данных, содержащихся в файле_1, файле источнике информации.

Причем в первичном потоке могут содержаться опции запуска, инициирующие вывод справки о данной программы, такие как - h и -- help (стандарт POSIX).

 

Пункт 3.

Выходной поток данных работы программы может быть представлен:

1. Созданным программой переименованным файлом в случае успешного запуска программы.

2. Выводом в стандартный поток вывода, либо в стандартный поток ошибок сообщения об ошибке.

3. Выводом в стандартный поток вывода справочной информации об использовании данной программы.

При работе программы возможны следующие "ошибки":

1. Программа запущена с неверным числом параметров.

2. Программе передано имя несуществующего файла источника данных, либо у текущего пользователя нет прав для его обработки: чтение, переименование, удаление после создания копии с новым именем.

3. У пользователя, с чьими правами запущена программа, нет прав на создание нового файла, либо модификации существующего, в случае если происходи перезаписывание файла-приемника.

 

Пункт 4. (схема информационных потоков)

Участники информационного взаимодействия в данной программе:

Пользователь, Программа, Операционная система, Файлы на физическом носителе.

В качестве “Пользователя” данного ПС может выступать человек, оператор ПК, либо другая программа, в случае, если проектируемое ПС планируется использовать в качестве программного сервиса (программы, работающей под управлением другой программы).

Состав участников информационно цепи:

”Источник Информации” - ”Приемник Информации” - зависит от конкретного этапа работы программы. Можно выделить следующие шаги-этапы в работе программы:

  1. Запуск программы. Пользователь (ИИ) → Программа (ПИ).
  2. Досрочное завершение работы программы с выдачей соответствующего сообщения. Программа (ИИ) → Пользователь, другая Программа (ПИ).
  3. Процесс создания копии файла под новым именем. Файлы на физическом носителе (ИИ) → Программа (ПИ) → Файлы на физическом носителе (ПИ).

Получаем следующую иерархию участников информационного обмена:

Пользователь <=> Программа <=> Операционная система <=> Файл.

 

Пункт 5. ( описание возможных "ошибок" при работе программы )

При работе программы возможны следующие "ошибки":

  1. программа запущена с недопустимым числом параметров, то есть число параметров запуска не равно 1 — запуск без параметров, либо 2 — запуск с опцией получение справки о программе, либо 3 — запуск в ”штатном” режиме;
  2. программе передано имя несуществующего файла источника данных, либо у текущего пользователя нет прав для его обработки: чтение, переименование, удаление после создания копии с новым именем;
  3. у пользователя, с чьими правами запущена программа, нет прав на создание нового файла, либо модификации существующего, в случае если происходи перезаписывание файла-приемника;
  4. ошибки в файловом потоке, в том числе при обработке слишком длинных файлов, либо при нарушении целостности структуры файла, отсутствие символа EOF.

 

Пункт 6. ( правила обработки ошибок )

В случае запуска программы с недопустимым числом параметров программа должна выдать соответствующее сообщение в стандартный поток ошибок STDERR: “Слишком большое число аргументов, переданных программе” и завершить свою работу с возвратом операционной системе значения 1 (exit(1); либо return 1;).

В случае отказа в доступе к файлу источнику данных программа выдает соответствующее сообщение в стандартный поток ошибок STDERR: ”у текущего пользователя нет прав чтения файла <указывается имя файла>” и завершить свою работу с возвратом операционной системе значения 2 (exit(2); либо return 2;).

В случает отказа со стороны операционной системы в праве на создание файл приемник информации программа выдает соответствующее сообщение в стандартный поток ошибок STDERR: ”у текущего пользователя нет прав создания файла в указанной директории” и завершить свою работу с возвратом операционной системе значения 3 (exit(3); либо return 3;).

В случае если программа создала копию файла под новым именем, но у пользователя, с чьими правами запущена данная программа, нет прав на удаление файла источника данных, либо для него выставлен атрибут ”Read Only” (только для чтения), программа должна удалить, если это возможно, созданную под новым именем копию файла и в стандартный поток ошибок STDERR выдать сообщение: ”ошибка при переименовании — перемещении файла”, и завершить свою работу с возвратом операционной системе значения 4 (exit(4); либо return 4;).

 

Пункт 7. ( Описание этапов последовательного, пошагового выполнения программы. Выделение функциональных блоков и описание их в виде отдельных модулей, функций )

  1. чтение количества аргументов функции main (int argc, char ** argv), значения переменной argc.
  2. если количество аргументов больше трех, то досрочное завершение работы программы с выдачей соответствующего сообщения.
  3. если количество аргументов равно одному — программа запущена без параметров (argc ==1) программа выводит справочную информацию о себе, содержащую справку о формате запуска.
  4. если количество аргументов равно двум и опция запуска содержит ключ ”- h ” ”-- help ”, то программа запущена в режиме вывода расширенной справки о ее использовании, включающую контактную информацию о разработчике.

if((argc==2)&&((!strcmp(argv[1],”-h”))

||(! strcmp (argv [1],"— help ")))

После вывода соответствующей информации программа завершает свою работу.

  1. if (argc ==3) полагаем, что программа запущена в штатном режиме переименования файла. Интерпретируем значения строк argv [1] и argv [2] как соответствующие исходное старое и новое имена файла. Организуем процедуры открытия файлов в соответствующих режимах.

Пункт 8. ( Описание пошагового сценария работы программы с организацией ветвления при реализации логики работы программы как в штатном, нормальном режиме работы, так и в случае обработки ошибок. Составление обобщенной блок схемы функционирования приложения )

Пункт 9. ( размеченный граф состояний, соответствующий пошаговой работе программы )

Пункт 10. ( Исходя из номеров вершин в графе, описывающем ПО, определить значения, возвращаемые функциями-модулями с учетом обработки ошибок и досрочного завершения работы программы )

Пункт 11. ( Перейти от линейной структуры пошагового исполнения к циклической, а внутри цикла процедуру множественного выбора-ветвления.)

while(step!=0)

{

switch(step)

  {

     case 1: …; step=2; break;

     case 2: …; step=3; break;

     case 3: …; step=4; break;

     case 4: …; step=0; break;

     default: perror(“Error!”);/* обработка внути-

                             программных ошибок */

}

 

Примечания

1. Термины ”первичный” и ”вторичный” потоки данных введены автором для описания порядка их обработки, в порядке создания-порождения.

2. В данном случае под понятием "ошибка" подразумевается не сбой в работе программы, а нарушение нормального режима работы программы, приводящего к реализации главной функции программы, ради которой она создана, в следствии передаче программе заведомо неверных данных. Это не ошибка исполнения программы, а несоблюдение правил диалога между пользователем и программой, либо между взаимодействующими программами. Данные "ошибки" можно описать на этапе проектирования и в состав ПО ввести средства их обработки, как средства обработки внештатных ситуаций.

Приложение 2.

Условное обозначение элементов блок-схемы

 

Данный раздел составлен на основании ГОСТ 19.701-90 (ИСО 5807-85) Единая система программной документации. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения.

 

Символ обозначения Использование

Символы данных

Символ данных. Символ отображает данные, носитель данных не определен.
Запоминаемые данные. Символ отображает хранимые данные в виде, пригодном для обработки, носитель данных не определен.
Специфические символы данных Оперативное запоминающее устройство Символ отображает данные, хранящиеся в оперативном запоминающем устройстве.
Запоминающее устройство с последовательным доступом Символ отображает данные, хранящиеся в запоминающем устройстве с последовательным доступом (магнитная лента, кассета с магнитной лентой, магнитофонная кассета).
Запоминающее устройство с прямым доступом Символ отображает данные, хранящиеся в запоминающем устройстве с прямым доступом (магнитный диск, магнитный барабан, гибкий магнитный диск).
Документ Символ отображает данные, представленные на носителе в удобочитаемой форме (машинограмма, документ для оптического или магнитного считывания, микрофильм, рулон ленты с итоговыми данными, бланки ввода данных).
Ручной ввод. Символ отображает данные, вводимые вручную во время обработки с устройств любого типа (клавиатура, переключатели, кнопки, световое перо, полоски со штриховым кодом).
Карта Символ отображает данные, представленные на носителе в виде карты (перфокарты, магнитные карты, карты со считываемыми метками, карты с отрывным ярлыком, карты со сканируемыми метками).
Дисплей Символ отображает данные, представленные в человекочитаемой форме на носителе в виде отображающего устройства (экран для визуального наблюдения, индикаторы ввода информации).

Символы процесса

Процесс Символ отображает функцию обработки данных любого вида (выполнение определенной операции или группы операций, приводящее к изменению значения, формы или размещения информации или к определению, по которому из нескольких направлений потока следует двигаться).
Ручная операция Символ отображает любой процесс, выполняемый человеком.
Подготовка Символ отображает модификацию команды или группы команд с целью воздействия на некоторую последующую функцию (установка переключателя, модификация индексного регистра или инициализация программы).
Решение Символ отображает решение или функцию переключательного типа, имеющую один вход и ряд альтернативных выходов, один и только один из которых может быть активизирован после вычисления условий, определенных внутри этого символа. Соответствующие результаты вычисления могут быть записаны по соседству с линиями, отображающими эти пути
Параллельные действия Символ отображает синхронизацию двух или более параллельных операций.
Граница цикла Символ, состоящий из двух частей, отображает начало и конец цикла. Обе части символа имеют один и тот же идентификатор. Условия для инициализации, приращения, завершения и т.д. помещаются внутри символа в начале или в конце в зависимости от расположения операции, проверяющей условие.

Символы линий

Линия Символ отображает поток данных или управления.
Передача управления Символ отображает непосредственную передачу управления от одного процесса к другому, иногда с возможностью прямого возвращения к инициирующему процессу после того, как инициированный процесс завершит свои функции. Тип передачи управления должен быть назван внутри символа (например, запрос, вызов, событие).
Пунктирная линия Символ отображает альтернативную связь между двумя или более символами. Кроме того, символ используют для обведения аннотированного участка.
   
   
   

 


 

========================================================================

Работа с файлами.

Файлы представляют собой области памяти на внешнем носителе (как правило магнитном диске), предназначенные для:

  • хранения данных, превосходящих по объему память компьютера (меньше, разумеется, тоже можно);
  • долговременного хранения информации (она сохраняется при выключении машины).

В UNIX и в MS DOS файлы не имеют предопределенной структуры и представляют собой просто линейные массивы байт. Если вы хотите задать некоторую структуру хранимой информации - вы должны позаботиться об этом в своей программе сами.

Файлы отличаются от обычных массивов тем, что

  • они могут изменять свой размер;
  • обращение к элементам этих массивов производится не при помощи операции индексации [], а при помощи специальных системных вызовов и функций;
  • доступ к элементам файла происходит в так называемой "позиции чтения/записи", которая автоматически продвигается при операциях чтения/записи, т.е. файл просматривается последовательно. Есть, правда, функции для произвольного изменения этой позиции.

Файлы имеют имена и организованы в иерархическую древовидную структуру из каталогов и простых файлов. Об этом и о системе именования файлов прочитайте в документации по UNIX.

4.1.

Для работы с каким-либо файлом наша программа должна открыть этот файл - установить связь между именем файла и некоторой переменной в программе. При открытии файла в ядре операционной системы выделяется "связующая" структура file " открытый файл ", содержащая:
f _ offset: указатель позиции чтения/записи, который в дальнейшем мы будем обозначать как
RWptr. Это long -число, равное расстоянию в байтах от начала файла до позиции чтения/записи;
f _ flag: режимы открытия файла: чтение, запись, чтение и запись, некоторые дополнительные флаги;
f _ inode: расположение файла на диске (в UNIX - в виде ссылки на I-узел файла *);
и кое-что еще.

У каждого процесса имеется таблица открытых им файлов - это массив ссылок на упомянутые "связующие" структуры **. При открытии файла в этой таблице ищется

- длина файла             long di _ size; - номер владельца файла   int di _ uid; - коды доступа и тип файла ushort di _ mode; - время создания и последней модификации               time _ t di _ ctime, di _ mtime; - начало таблицы блоков файла char di _ addr [...]; - количество имен файла   short di _ nlink; и.т.п.

Содержимое некоторых полей этого паспорта можно узнать вызовом stat (). Все I-узлы собраны в единую область в начале файловой системы - так называемый I-файл. Все Iузлы пронумерованы, начиная с номера 1. Корневой каталог (файл с именем " / ") как правило имеет I-узел номер 2.

** - У каждого процесса в UNIX также есть свой "паспорт". Часть этого паспорта находится в таблице процессов в ядре ОС, а часть - "приклеена" к самому процессу, однако не доступна из программы непосредственно. Эта вторая часть паспорта носит название " u-area " или структура user. В нее, в частности, входят таблица открытых процессом файлов, свободная ячейка, в нее заносится ссылка на структуру "открытый файл" в ядре, и ИНДЕКС этой ячейки выдается в вашу программу в виде целого числа - так называемого " дескриптора файла ".

При закрытии файла связная структура в ядре уничтожается, ячейка в таблице считается свободной, т.е. связь программы и файла разрывается.

Дескрипторы являются локальными для каждой программы. Т.е. если две программы открыли один и тот же файл - дескрипторы этого файла в каждой из них не обязательно совпадут (хотя и могут). Обратно: одинаковые дескрипторы (номера) в разных программах не обязательно обозначают один и тот же файл. Следует учесть и еще одну вещь: несколько или один процессов могут открыть один и тот же файл одновременно несколько раз. При этом будет создано несколько "связующих" структур (по одной для каждого открытия); каждая из них будет иметь СВОЙ указатель чтения/записи. Возможна и ситуация, когда несколько дескрипторов ссылаются к одной структуре - смотри ниже описание вызова dup2.

fd u _ ofile []     struct file 0 ##            ------------ 1---##---------------->| f _ flag | 2 ##            | f _ count =3 | 3---##---------------->| f _ inode ---------*... ## *-------------->| f _ offset | | процесс1 |          ------!------ |        |               !      V 0 ## | struct file   ! struct inode 1 ## | -------------! ------------- 2---##-* | f _ flag |! | i _ count =2 | 3---##--->| f _ count =1 |! | i _ addr []----*... ## | f _ inode ----------!-->|... | | адреса процесс2 | f _ offset |! ------------- | блоков           -------!----- *=========*  | файла                 !               !  V       0    ! указатели R/W! i _ size -1       @@@@@@@@@@@!@@@@@@@@@@@@@@@@@@@@@!@@@@@@                      файл на диске /* открыть файл */ int fd = open (char имя _ файла [], int как _ открыть);      ... /* какие-то операции с файлом */ close (fd); /* закрыть */

Параметр как _ открыть:

#include < fcntl. h > O _ RDONLY - только для чтения. O _ WRONLY - только для записи. O _ RDWR - для чтения и записи. O _ APPEND - иногда используется вместе с открытием для записи, "добавление" в файл:   O _ WRONLY | O _ APPEND, O _ RDWR | O _ APPEND

Если файл еще не существовал, то его нельзя открыть: open вернет значение (-1),

struct file * u _ ofile [NOFILE];

ссылка на I-узел текущего каталога

struct inode * u _ cdir;

а также ссылка на часть паспорта в таблице процессов

struct proc * u _ procp;

сигнализирующее об ошибке. В этом случае файл надо создать:

int fd = creat (char имя _ файла [], int коды _ доступа);

Дескриптор fd будет открыт для записи в этот новый пустой файл. Если же файл уже существовал, creat опустошает его, т.е. уничтожает его прежнее содержимое и делает его длину равной 0L байт. Коды _ доступа задают права пользователей на доступ к файлу. Это число задает битовую шкалу из 9и бит, соответствующих строке

биты: 876 543 210       rwx rwx rwx r - можно читать файл w - можно записывать в файл x - можно выполнять программу из этого файла

Первая группа - эта права владельца файла, вторая - членов его группы, третяя - всех прочих. Эти коды для владельца файла имеют еще и мнемонические имена (используемые в вызове stat):

#include <sys/stat.h> /* Там определено: */ #define S _ IREAD       0400 #define S _ IWRITE      0200 #define S _ IEXEC       0100

Подробности - в руководствах по системе UNIX. Отметим в частности, что open () может вернуть код ошибки fd < 0 не только в случае, когда файл не существует (errno == ENOENT), но и в случае, когда вам не разрешен соответствующий доступ к этому файлу (errno == EACCES; про переменную кода ошибки errno см. в главе "Взаимодействие с UNIX ").

Вызов creat - это просто разновидность вызова open в форме

fd = open (имя _ файла,          O _ WRONLY | O _ TRUNC | O _ CREAT, коды _ доступа);

O _ TRUNC

означает, что если файл уже существует, то он должен быть опустошен при открытии. Коды доступа и владелец не изменяются.

O _ CREAT

означает, что файл должен быть создан, если его не было (без этого флага файл не создастся, а open вернет fd < 0). Этот флаг требует задания третьего аргумента

коды _ доступа ***.

Если файл уже существует - этот флаг не имеет никакого эффекта, но зато вступает в действие O _ TRUNC.

Существует также флаг

O _ EXCL

который может использоваться совместно с O _ CREAT. Он делает следующее: если файл уже существует, open вернет код ошибки (errno == EEXIST). Если файл не

*** - Заметим, что на самом деле коды доступа у нового файла будут равны

di _ mode = (коды _ доступа & ~ u _ cmask) | IFREG;

(для каталога вместо IFREG будет IFDIR), где маска u _ cmask задается системным вызовом

umask (u _ cmask);

(вызов выдает прежнее значение маски) и в дальнейшем наследуется всеми потомками данного процесса (она хранится в u - area процесса). Эта маска позволяет запретить доступ к определенным операциям для всех создаваемых нами файлов, несмотря на явно заданные коды доступа, например

umask (0077); /*???------ */

делает значащими только первые 3 бита кодов доступа (для владельца файла). Остальные биты будут равны нулю.

Все это относится и к созданию каталогов вызовом mkdir.

существовал - срабатывает O _ CREAT и файл создается.

Это позволяет предохранить уже существующие файлы от уничтожения.

Файл удаляется при помощи

int unlink (char имя _ файла []);

У каждой программы по умолчанию открыты три первых дескриптора, обычно связанные

0 - с клавиатурой (для чтения) 1 - с дисплеем (выдача результатов) 2 - с дисплеем (выдача сообщений об ошибках)

Если при вызове close (fd) дескриптор fd не соответствует открытому файлу (не был открыт) - ничего не происходит.

Часто используется такая метафора: если представлять себе файлы как книжки (только чтение) и блокноты (чтение и запись), стоящие на полке, то открытие файла это выбор блокнота по заглавию на его обложке и открытие обложки (на первой странице). Теперь можно читать записи, дописывать, вычеркивать и править записи в середине, листать книжку! Страницы можно сопоставить блокам файла (см. ниже), а "полку" с книжками - каталогу.

4.2.

Напишите программу, которая копирует содержимое одного файла в другой (новый) файл. При этом используйте системные вызовы чтения и записи read и write. Эти сисвызовы пересылают массивы байт из памяти в файл и наоборот. Но любую переменную можно рассматривать как массив байт, если забыть о структуре данных в переменной!

Читайте и записывайте файлы большими кусками, кратными 512 байтам. Это уменьшит число обращений к диску. Схема:



Поделиться:


Последнее изменение этой страницы: 2021-06-14; просмотров: 70; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.16.69.143 (0.109 с.)