CFA LogoCFA Logo Computer
Новости Статьи Магазин Прайс-лист Драйвера Контакты
Новости
RSS канал новостей
В конце марта компания ASRock анонсировала фирменную линейку графических ускорителей Phantom Gaming. ...
Компания Huawei продолжает заниматься расширением фирменной линейки смартфонов Y Series. Очередное ...
Компания Antec в своем очередном пресс-релизе анонсировала поставки фирменной серии блоков питания ...
Компания Thermalright отчиталась о готовности нового высокопроизводительного процессорного кулера ...
Компания Biostar сообщает в официальном пресс-релизе о готовности флагманской материнской платы ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2003 ГОД

Мысли о Паскале

Владислав ДЕМЬЯНИШИН nitromanit@mail.ru

Продолжение, начало см. в МК №46, 51-52, 4, 6-7, 10, 12-13, 16-18, 22, 24, 29, 34, 41, 46, 4, 6, 17, 21, 23, 28, 30, 32, 39, 42, 45, 47 (165, 170-171, 175, 177-178, 181, 183-184, 187-189, 193, 195, 200, 205, 212, 217, 227, 229, 240, 244, 246, 251, 253, 255, 262, 265, 268, 270).

Навигация по файлу

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

Процедура Seek(var F; N : longint) позиционирует указатель на элемент N (нумерация с нуля) открытого файла, представленного файловой переменной F. После этого текущая позиция указателя файла устанавливается на N-й элемент, и последующие операции чтения/записи будут проводиться с этой позиции. Если в качестве новой позиции в файле указать значение, равное или превышающее размер файла в элементах, то значение текущего указателя будет установлено на окончание файла.

Функция FileSize(var F):longint возвращает размер открытого файла, представленного файловой переменной F, в элементах базового типа.

Функция FilePos(var F):longint возвращает текущую позицию указателя (номер текущего элемента) открытого файла, представленного файловой переменной F.

Функция EoF(var F):boolean возвращает True, если достигнут конец файла, и False в противном случае; F — файловая переменная.

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

Специальные операции

Следует перечислить некоторые операции, предназначенные для манипуляций с элементами файловой системы MS-DOS — файлами и каталогами (папками).

Операция удаления файла Erase(var F) вызывается с указанием файловой переменной, при этом файл может быть связан с этой переменной и даже открыт. В любом случае после вызова Erase закрывать файл не имеет смысла (закрывать нечего), поэтому строку Close(FileWord) можно опустить:

Операция переименования (переброски) файла Rename(var F; NewName : string) требует указания присоединенной файловой переменной, а также строку с новым именем файла:

При этом файл не следует открывать, иначе при выполнении команды Rename произойдет ошибка Error 5: File access denied — запрещен доступ к файлу (то бишь к words.dat, который следует переименовать). Данная ошибка может возникнуть еще и тогда, когда файл с новым именем уже существует (в нашем случае — файл awords.dat). Если же переименовываемый файл отсутствует, то возникает ошибка Error 2: File not found (файл не найден). Указание такого короткого имени файла (без пути) приемлемо лишь для файла, который находится в текущем каталоге (с программой или же установленном командой ChDir), а если необходимо файл не просто переименовать, но еще и перебросить его в другое место на диске, то тогда следует указать новое имя файла и путь, куда его следует переместить —Rename(FileWord,'d:\awords.dat'). Так как файл открыт не был, то и закрывать его операцией Close не нужно. Есть маленький нюанс, который может быть чреват серьезными неудобствами, и состоит он в том, что при попытке перебросить файл с одного диска на другой произойдет ошибка выполнения. Так, строки

вызовут ошибку Error 17: Cannot rename across drives (нельзя переименовать с диска на диск). Отсюда вывод: можно переименовывать файлы в пределах одного диска.

Операция MkDir(S : string) создает новый подкаталог с именем S. Для создания папки files в текущей папке —MkDir('files'), для создания новой папки в корневом каталоге D-диска —MkDir('d:\files').

Для удаления папки следует вызвать RmDir(S : string) с именем папки в текущем каталоге RmDir('files') или с указанием полного пути к папке RmDir('d:\files').

Для смены текущей папки следует вызывать операцию ChDir(S:string) с тем же именем папки, что и для предыдущей операции, а проверить, какая папка на данный момент является текущей, можно при помощи процедуры GetDir(D:byte; var S:string) с указанием номера диска D и получением имени текущей папки в строке S. При этом следует указать номер диска 0 для текущего диска или номера 1,2,3,4,5,… для дисков A,B,C,D,E,… соответственно. Пример:

Чтобы перейти на один уровень дерева папок выше, следует выполнить ChDir('..') с двумя точками в качестве параметра.

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

Для получения информации о размере диска в байтах следует вызвать функцию DiskSize(Drive:Byte):longint стандартного модуля DOS, где параметр Drive указывает номер диска в соответствии со сказанным выше. При этом если размер логического диска превышает 2 Гб, все равно будет получен результат 2 Гб.

Для получения информации о свободном пространстве (в байтах) на диске следует вызвать функцию DiskFree(Drive:Byte):longint модуля DOS. Аналогичная ситуация и с 2 Гб.

Две последние функции тоже могут вызвать аварийное завершение программы при возникновении ошибки, если не выполнить директиву {$I–}; кроме того, они никак не влияют на значение, возвращаемое системной функцией IOResult, о которой пойдет речь далее. Однако данные функции в случае ошибки возвращают значение –1, если указанный диск отсутствует.

Еще модуль DOS предоставляет несколько полезных подпрограмм. Функция FSearch(Path:PathStr; DirList:string):PathStr производит поиск файла с именем Path в текущей папке, и если файл не найден, то поиск выполняется по каждому пути из списка DirList, где они перечислены через точку с запятой. При этом DirList может быть пустой строкой. В случае удачного поиска будет возвращена строка с именем искомого файла, иначе будет возвращена пустая строка.

Получить полный путь к файлу можно, вызвав функцию Expand(Path:PathStr):PathStr, где Path — имя файла. Данная функция не проверяет наличие указанного файла на диске, а просто дополняет имя файла недостающими параметрами — именем текущего диска и путем к текущему каталогу.

Процедура FSplit(Path:PathStr; var Dir:DirStr; var Name:NameStr; var Ext:ExtStr) позволяет разложить полное имя файла Path на составляющие: путь к файлу в Dir, короткое имя файла в Name и окончание (расширение) имени файла в Ext. Примеры смотрите ниже.

Нельзя не упомянуть о двух очень полезных процедурах, которые позволяют строить конструкции поиска файлов и папок по указанному пути и маске. Процедура FindFirst(Path:string; Attr:word; var S:SearchRec) производит поиск первого файла или папки по указанному пути Path, результат же поиска заносит в переменную S типа SearchRec, который описан в модуле DOS как:

данная структура не выдумана разработчиками Turbo Pascal, а продиктована интерфейсом сервиса MS-DOS. Имена полей говорят сами за себя. Разве что значения поля Attr следует расшифровать. Данное поле хранит признак элемента каталога — грубо говоря, показывает, папка это или файл.

Процедура FindNext(var S:SearchRec) предназначена для поиска каждого последующего элемента каталога; предварительно должна быть вызвана процедура FindFirst. Процедуры FindFirst и FindNext модифицируют значение переменной DosError, объявленной в модуле DOS, поэтому после выполнения любой из этих двух процедур следует проверять ее значение. Если значение равно нулю, значит, поиск проведен успешно, можно продолжать искать далее; если нет, нас либо постигла неудача, либо уже были найдены все элементы, отвечающие критериям Path. При этом параметр Path может быть либо пустой, и тогда поиск будет проводиться в текущей папке, либо может содержать путь поиска и маску поиска. Основываясь на многолетней практике, могу сказать, что параметр Attr процедурой FindFirst никак не учитывается, поэтому после очередного поиска следует проверять атрибут найденного элемента каталога. Вот пример поиска файлов по пути и маске:

А это пример поиска папок:

при этом отсекаем ненужное. А следом идет пример, показывающий, как использовать представленные выше процедуры:

Впрочем, я немного увлекся рассмотрением модуля DOS, совсем забыв о главной сегодняшней теме.

Обработка ошибок ввода-вывода

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

В итоге стараниями системы наша программа может быть прервана в самый неподходящий момент. Как говорится, только жениться собрался… пардон, сохранить заветные данные на диск — а там, глядишь, свободные места все вышли.

Чтобы взять быка за рога (в данном случае — позволить обработать аварийную ситуацию самой программе), следует перед фрагментом кода с дисковыми операциями установить директиву {$I–} — тогда программа не будет завершена аварийно, зато можно будет получить код возникшей ошибки посредством вызова функции IOResult (0 — ошибки нет). Следует производить проверку возвращаемого значения данной функции после каждой дисковой операции, которая может вызвать ошибку, — если функция IOResult не была вызвана сразу после ошибки, дальнейшие дисковые операции будут заблокированы и проигнорированы. При этом данная функция возвращает код ошибки только раз, а затем обнуляет этот код — теперь последующие вызовы этой функции будут давать нулевой результат до тех пор, пока какая-нибудь ошибка не произойдет снова.

Рассмотрим на примере:

Предложенная конструкция обработки ошибок позволяет предотвратить проблемы при выполнении процедуры Reset, предполагающей наличие открываемого файла. Есть и другой вариант, когда может быть предотвращено само возникновение ошибки — в этом случае задействованы подпрограммы FSearch, FExpand и FSplit:

Наконец, чтобы дополнительными ошибками не грозил человеческий фактор, напомню следующее:

имя файла — это любое выражение строкового типа, построенное по правилам составления файловых имен в операционной системе MS-DOS, где имя может содержать не более восьми допустимых символов. Допустимые символы — это прописные и строчные латинские буквы, цифры и символы !, @, #, $, %, ^, &, (, ), ', ~, -, _;

имя файла может начинаться с любого допустимого символа;

за именем может следовать расширение — последовательность не более трех допустимых символов, отделенная от имени точкой;

перед именем может быть указан так называемый путь к файлу: имя диска и/или имя текущего каталога, а также имена каталогов (папок) вышестоящих уровней;

имя диска — это один из символов A..Z, после которого следует двоеточие. Имена А: и В: ассоциируются с дисковыми накопителями на гибких магнитных дискетах (НГМД), имена С:, D:, … — соответственно, с жесткими дисками (НЖМД). Вслед за именем диска может идти имя каталога, содержащего файл. Когда имени каталога предшествует обратная косая черта, путь к файлу начинается с корневого каталога, если черты нет — из текущего каталога. За именем каталога может следовать одно или несколько имен каталогов нижнего уровня (подкаталогов), а каждое из них должна предварять обратная косая черта. Весь путь к файлу отделяется от имени файла обратной косой чертой. Максимально допустимая длина имени файла вместе с путем к нему — 79 символов. Для этого в модуле DOS объявлен тип PathStr : string[79].

(Продолжение следует)

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы или вычислите пример: *
captcha
Обновить





Хостинг на серверах в Украине, США и Германии. © www.sector.biz.ua 2006-2015 design by Vadim Popov