- •От автора
- •1. Общая схема решения задачи на персональном компьютере
- •2. Структура программы на языке Паскаль
- •3. Арифметические типы данных. Числовые константы и переменные. Оператор присваивания. Выражение
- •4. Операторы ввода-вывода
- •5. Арифметические операции. Стандартные математические функции
- •6. Символьный тип данных
- •7. Логический тип данных. Операции сравнения. Логические операции
- •8. Условный оператор. Блок. Оператор выбора
- •9. Операторы цикла
- •10. Метки. Оператор Goto. Процедура Halt
- •11. Интервальные типы данных. Оператор Type. Массивы
- •Var a : Array[1..33000] Of Word;
- •Var a : Array[1..3] Of Real;
- •Var e,f : Massiv;
- •Var a : Array[1..10] Of Array[1..20] Of Real;
- •12. Процедуры и функции. Сфера действия описаний
- •13. Открытые массивы и нетипизированные параметры
- •14. Множества
- •15. Тип String
- •16. Графические средства языка Паскаль
- •17. Особенности вещественных вычислений
- •18. Записи
- •19. Тип "перечисление"
- •20. Модуль Crt
- •Var TextAttr : Byte
- •21. Модули. Создание и использование модулей
- •Interface
- •Implementation
- •22. Файлы
- •23. Другие средства обработки файлов и модуль dos
- •24. Процедурные типы
- •25. Указатели и динамическая память
- •26. Динамические структуры: списки, деревья
- •27.Открытые строки
- •28. Использование командной строки и вызов внешних программ
- •29. Обработка программных прерываний
- •30. Объекты
- •31.Рекурсия и динамическое программирование
- •32. Рекурсия и стек отложенных заданий
- •33. Стеки и очереди
- •34. Комбинаторные алгоритмы
- •35. Бинарные деревья
- •36. Упорядоченные бинарные деревья и приоритетные очереди
- •37. Алгоритмы сортировки
- •38. Графы
- •Рекомедуемая литература
- •Содержание
23. Другие средства обработки файлов и модуль dos
Для того чтобы определить, есть ли на диске файл с заданным именем, удобно использовать уже известную нам стандартную функцию IOResult , которая возвращает ноль при успешном завершении последней операции ввода-вывода и ненулевое значение в случае ошибки. Открытие файла также является операцией ввода-вывода, а открытие несуществующего файла процедурой Reset является ошибкой. Запишем программу, которая будет вводить имя файла и определять, есть ли такой файл в текущей директории.
Var
Name : String[12];
f : File;
Begin
Write(‘Введите имя файла ’);
ReadLn(Name);
Assign(f,Name); {инициализируем файл, пока не важно, существует ли он}
{$I-} {отключаем контроль ошибок ввода-вывода, чтобы избежать аварийного завершения программы}
Reset(f); {если файла нет, то IOResult вернет не ноль}
If IOResult<>0 Then Begin WriteLn(‘Файла нет’); Halt(1); End;
{$I+} {вновь включаем контроль ошибок ввода-вывода}
{здесь можно читать файл }
End.
В Паскале есть четыре стандартных процедуры для работы с директориями:
Procedure GetDir(Disk : Byte; Var Dir : String) - возвращает полное имя (включающее путь) текущей директории на указанном диске, входной параметр Dir может принимать значения 0 - текущий диск, 1 - диск A, 2 - диск B,... 26 - диск Z.
Procedure ChDir(Dir : String) - позволяет перейти в директорию, заданную параметром Dir, аналогична команде chdir (или cd) операционной системы DOS. Значением параметра Dir может быть как полное имя директории, так и простое имя, в этом случае она считается поддиректорией текущей директории. Если директории Dir не существует, происходит ошибка ввода-вывода.
Procedure MkDir(Dir : String) - создает поддиректорию текущей директории с именем Dir, аналогична одноименной команде DOS; если такая директория уже существует, происходит ошибка ввода-вывода.
Procedure RmDir(Dir : String) - уничтожает поддиректорию Dir, аналогична одноименной команде DOS, если директория не пуста или ее не существует, происходит ошибка ввода-вывода. Используя опцию компилятора {$I-} и функцию IOResult, вы можете писать надежные программы, работающие с директориями, которые будут застрахованы от аварийных прерываний.
Модуль DOS объединяет средства, позволяющие выполнять некоторые функции операционной системы. Мы изучим лишь часть из них.
1. Procedure GetDate(Var Year, Month, Day, DayOfWeek: Word) - возвращает текущую дату: год, номер месяца, число и номер дня недели; 0 соответствует воскресенью, 6 - субботе.
2. Procedure GetTime(Var Hour, Minute, Second, Sec100: Word) - возвращает текущее время: часы, минуты, секунды и сотые доли секунды.
3. Procedure FindFirst(Mask: String; Attr: Byte; Var F: SearchRec) - ищет в текущей или указанной директории первый файл, соответствующий заданной маске и атрибуту. Возвращает информацию о файле в переменной F. Маска может включать путь (если путь не задан, то поиск происходит в текущей директории) и должна содержать либо имя файла, либо шаблон (с использованием символов * и ?). Параметр Attr может принимать одно из следующих значений :
ReadOnly =$01 - файл только для чтения,
Hidden =$02 - скрытый файл,
SysFile =$04 - системный файл,
VolumeID =$08 - заголовок тома,
Directory =$10 - директория,
Archive =$20 - архивный файл,
AnyFile =$3F - любой файл
либо быть равным сумме какой-нибудь комбинации этих констант. Тип SearchRec определен в модуле DOS таким образом:
Type SearchRec = Record
Fill : Array[1..21] of Byte;
Attr : Byte;
Time : LongInt;
Size : LongInt;
Name : String[12];
End;
Здесь Attr - атрибут файла, Time - упакованное время создания файла, Size - размер файла в байтах, Name - имя файла, Fill - системное поле. Для распаковки времени создания файла служит процедура
4. Procedure UnpackTime(Time: LongInt; Var DT: DateTime) - распаковывает упакованное время Time и возвращает результат в записи DT, которая описана в модуле DOS так : Type DateTime = Record Year, Month, Day, Hour, Min, Sec : Word; End;
5. Procedure FindNext(Var F: SearchRec) - ищет следующий файл с атрибутами, заданными последним вызовом FindFirst. Процедуры FindFirst и FindNext возвращают через переменную
6. Var DosError : Integer
свой код завершения. Если значение этой переменной равно 0, процедура выполнилась успешно, в противном случае файл не был найден. Запишем программу, которая будет выводить на экран список файлов, имеющихся в текущей директории и всех ее поддиректориях.
Uses Dos;
Procedure Pass; {процедура выводит на экран полные имена всех файлов текущей директории и всех ее поддиректорий}
Var
R : SearchRec;
Dir : String;
Begin
GetDir(0,Dir); {определили полное имя текущей директории}
FindFirst('*.*',AnyFile,R); {ищем любой файл или директорию}
While DosError=0 Do With R Do Begin {пока файлы не кончились, продолжаем поиск}
If Attr And Directory=0 Then WriteLn(Dir+'\'+Name) {нашли файл}
Else {нашли директорию}
If Name[1]<>'.' Then Begin {это не директория '.' и не '..'}
ChDir(Name); {переходим в поддиректорию}
Pass; {ищем файлы в поддиректории}
ChDir('..'); {возвращаемся обратно}
End;
FindNext(R); {пытаемся найти еще какой-нибудь файл или директорию}
End;
End;
Begin
Pass;
End.
Процедура Pass в данной программе - рекурсивная, использование рекурсии в данной задаче естественно и позволяет сделать алгоритм очень простым и прозрачным, хотя, конечно, можно записать и нерекурсивный алгоритм. Более подробно рекурсивные алгоритмы и их применение мы рассмотрим позже.
Для поиска определенного файла на диске можно использовать функцию
7. Function FSearch(Name: PathStr; DirList: String): PathStr
Здесь Name - имя файла, возможно с добавлением пути (тип PathStr в модуле DOS определен как String[79]); DirList - список директорий, разделенных символами “;”. Функция возвращает полное имя файла, если он найден, или пустую строку.
Еще две функции модуля DOS предназначены для получения информации о логических дисках:
8. Function DiskSize(Disk: Byte): LongInt - возвращает размер логического диска в байтах, параметр Disk задает номер логического устройства : 0 - текущий диск, 1 - диск A, 2 - диск B, 3 - диск C и т.д. Если задан неверный номер устройства, функция возвращает значение -1, этим обстоятельством можно воспользоваться, чтобы проверить наличие какого-либо диска в данном компьютере.
9. Function DiskFree(Disk: Byte): LongInt - возвращает размер свободного пространства на заданном диске в байтах.
Для работы с атрибутами и временем создания файлов можно использовать процедуры
10. Procedure GetFAttr(Var f; Var Attr : Word) - возвращает атрибут файла, связанного с файловой переменной f.
11. Procedure SetFAttr(Var f; Attr : Word) - заменяет атрибут файла, связанного с файловой переменной f, на значение Attr.
12. Procedure GetFTime(Var f; Var Time : LongInt) - возвращает упакованное время создания файла, связанного с файловой переменной f.
13. Procedure SetFTime(Var f; Time : LongInt) - изменяет время создания файла, связанного с файловой переменной f, на значение Time (время задается в упакованном виде). Для успешного выполнения всех четырех процедур необходимо, чтобы файл был инициализирован и существовал на диске, открыт он или нет - не важно. Переменная DosError возвращает результат выполнения каждой из этих процедур (DosError=0 при успешном выполнении).