На этом шаге мы рассмотрим работу с файлами.
На этом шаге мы опишем несколько других предикатов для работы с файлами. Это предикаты filepos, eof, flush, existfile, deletefile, renamefile, disk и copyfile.
Предикат filepos может управлять позицией, где производится чтение или запись. Он имеет формат:
filepos(SymbolicFileName,FilePosition,Mode) % (i,i,i),(i,o,i)
Если FilePosition - связанная переменная, предикат может изменить позицию чтения и записи для файла с именем SymbolicFileName. Если при вызове FilePosition является свободной переменной, то SymbolicFileName возвращает текущую позицию в файле.
Mode является целой величиной и указывает, как должно интерпретироваться (согласно таблице 1) значение FilePosition.
Mode | FilePosition |
---|---|
0 | Относительно начала файла |
1 | Относительно текущей позиции |
2 | Относительно конца файла (конец файла соответствует позиции 0) |
Когда возвращается FilePosition, то filepos возвращает позицию относительно начала файла независимо от значения Mode.
Предикат eof проверяет, является ли позиция, полученная в процессе чтения, концом файла. В этом случае eof успешен. В противном случае он терпит неуспех. Предикат eof имеет вид:
eof(SymbolicFileName) % (i)
eof выдает ошибку во время выполнения, если файл был открыт с правами только на запись. Обратите внимание, что предикат не придает особого значения символу конца файла DOS (комбинация клавиш Ctrl+Z).
Пример, как предикат eof можно использовать для определения предиката repfile, который полезен при работе с файлами, repfile генерирует точку возврата до тех пока не будет достигнут конец файла.
predicates repfile(FILE) clauses repflie(_). repfile(F) :- not(eof(F)), repfile(F).
domains
file=input; output
predicates
convert_file
repfile(FILE)
clauses
convert_file:-
repfile(input),
readln(Ln), % Перевод букв строки в заглавные
upper_lower(LnInUpper,Ln) ,
write(LnInUpper),nl,
fail.
convert_file.
repfile(_).
repfile(F):-
not(eof(F)),
repfile(F).
goal
write("Which file do you want convert?"),
readln(InputFileName),nl,
write("What is the name of the output file?"),
readln(OutputFileName),nl,
openread(input,InputFileName),
readdevice(input),
openwrite(output,OutputFileName),
writedevice(output),
convert_file,
closefile(input),
closefile(output).
Предикат flush записывает содержимое внутреннего буфера в именованный файл. Он имеет формат.
flush(SymbolicFileName) % (i)
Предикат existfile выполняется успешно, если файл OSFileName будет найден. Формат его следующий:
existfile(OSFileName) % (i)
Предикат OSFileName может содержать каталог, а само имя может содержать знаки подстановки, как c:\psys\*.cfg. Предикат existfile завершается неуспешно, если имя файла не найдено в обозначенном пути каталога. Однако, заметьте, несмотря на то, что existfile находит все файлы, включая файлы с установленными атрибутами "system" (Системный) и "hidden" (Скрытый), он не находит каталоги.
Для проверки того, что файл присутствует на диске (прежде чем открывать его), вы можете воспользоваться:
open(File, Name):- existfile(Name), !, openread(File,Name). open(_, Name):- writeName("Error: the file",Name," is not found").
Предикат deletefile удаляет файл, заданный его аргументом, и имеет формат:
deletefile(OSFileName) % (i)
Предикат deletefile даст ошибку, если не сможет удалить файл. OSFileName не может содержать подстановочные символы.
Предикат renamefile переименовывает файл с именем OldOSFileName в NewOSFileName. Он имеет формат:
renamefile(OldOSFileName, NewOSFileName) %(i,i)
Предикат renamefile будет успешен, если файл с именем NewOSFileName не существует, и оба имени являются допустимыми файловыми именами. В противном случае будет выдана ошибка.
Предикат disk используется для изменения текущего диска и/или каталога/подкаталога и имеет формат:
disk(Path) %(i),(о)
При вызове со свободной переменной в качестве параметра, disk возвратит текущий каталог. В DOS-ориентированных версиях для переключения на другой диск без изменения существующего текущего каталога на этом диске используйте D:. Здесь D - буква, обозначающая устройство.
На следующем шаге мы рассмотрим основные предикаты управления строкой.