На этом шаге мы рассмотрим файловую систему.
На этом шаге мы представим вам файловую систему в Прологе и стандартные предикаты, обращающиеся с файлами. Познакомимся с переназначением ввода/вывода - эффективным методом связи ввода и вывода с различными устройствами.
Пролог использует current_readdevice (текущее устройство чтения), с которого считывается ввод, и current_write_device (текущее устройство записи), на которое посылается вывод. Как правило, текущим устройством чтения является клавиатура, а текущим устройством записи - экран дисплея. Однако вы можете назначить другие устройства. Например, ввод может читаться из файла, хранимого во внешней памяти (возможно, на диске). Можно даже переопределить устройства текущего ввода и вывода во время исполнения программы.
Независимо от того, какими устройствами чтения и записи вы пользуетесь, в программе на Прологе чтение и запись обрабатываются идентично. Для доступа к файлу вы должны сначала его открыть. Файл может быть открыт:
Файл открытый для любого действия, отличного от чтения, должен быть закрыт после завершения операции. В противном случае внесенные в файл изменения могут быть потеряны. Можно открыть несколько файлов одновременно. При этом и ввод вывод могут быть быстро переназначены между открытыми файлами. Открытие и закрытие файлов занимает намного больше времеми, чем переназначение потоков данных между ними.
Когда Пролог открывает файл, он связывает символическое имя с действительным именем файла операционной системы и использует это символическое имя для направления ввода и вывода. Символические имена файлов должны начинаться с маленькой буквы и должны быть объявлены в описании домена file. Например:
file=file1; source; auxiliary; somethingElse
В любой программе разрешен только один домен file. Пролог распознает пять встроенных альтернатив file, описанных в таблице 1.
Альтернатива | Описание |
---|---|
keyboard | Чтение с клавиатуры (по умолчанию) |
screen | Запись в монитор |
stdin | Чтение из стандартного ввода |
stdout | Запись в стандартный вывод |
stderr | Запись на стандартное устройство для вывода ошибок |
Эти встроенные альтернативы не должны встречаться в описании file. Открывать и закрывать их не требуется.
Следующие разделы описывают стандартные предикаты для открытия и закрытии файлов.
Например, строка:
"с:\\prolog\\include\\iodecl.con"представляет путь доступа к файлу:
с:\prolog\include\iodecl.conПредикат openread открывает файл OSFileName дли чтения, используя формат:
openread(SymbolicFileName,OSFileName) % (i, i)
Пролог обращается к открытому файлу по символическому имени SymbolicFileName, объявленному в домене file. Если файл не может быть открыт, Пролог выдаст сообщение об ошибке.
Предикат openwrite открывает файл OSFileName для записи, используя формат:
openwrite(SymbolicFileName,OSFileName) % (i,i)
Если файл уже существует, то он уничтожается. В противном случае Пролог создает новый файл и помещает его в соответствующем каталоге. Если файл не может быть создан, Пролог выдаст сообщение об ошибке.
Предикат openappend открывает файл OSFileName для записи в конец файла. При этом используется формат:
openappend(SymbolicFileName,OSFileName) % (i,i)
Если файл не может быть открыт на запись, Пролог сообщит об ошибке.
Предикат openmodify открывает файл OSFileName и для записи, и для чтения; если файл уже существует, он не будет перезаписан, openmodify имеет формат:
openmodify(SymbolicFileName,OSFileName) % (i,i)
Если система не может открыть OSFileName, Пролог сообщит об ошибке. Для заполнения файла с произвольным доступом предикат openmodify может использоваться вместе со стандартным предикатом filepos.
При открытии файла в текстовом режиме предикат filemode устанавливает указанный файл в текстовый или двоичный режим, используя формат:
filemode(SymbolicFileName,FileMode) % (i,i)
Если FileMode=0, файл SymbolicFileName устанавливается в двоичный режим; если FileMode=1, то он устанавливается в текстовый режим.
В текстовом режиме при записи к новым строкам добавляются символы "возврат каретки"\"перевод строки", а при чтении эта пара символов интерпретируется как новая строка.
Carriage return (возврат каретки) = ASCII 13
Line feed (перевод строки) = ASCII 10
В двоичном режиме никаких преобразований не производится. Для чтения двоичного файла вы можете использовать только предикат readchar или предикаты для доступа к двоичным файлам.
Предикат closefile закрывает указанный файл; он использует формат:
closefile(SymbollcFileName) % (i)
Этот предикат всегда завершается успешно, даже если файл не был открытым.
Предикат readdevice переопределяет current_read_device (текущее устройство чтения) или возвращает его имя. Предикат имеет формат:
readdevice(SymbolicFileName) % (i), (о)
Предикат readdevice переопределяет текущее устройство чтения, если переменная SymbolicFileName определена, и файл открыт для чтения. Если SymbolicFileName является свободной переменной, то readdevice присвоит ей имя текущего активного устройства чтения.
Предикат writedevice либо назначает, либо позволяет получить имя current_ write_device (текущего устройства записи). Он имеет формат:
writedevice(SymbolicFileName) % (i), (о)
Предикат writedevice переопределит устройство записи, если указанный файл открыт для записи или добавления. Если переменная SymbolicFileName свободна, writedevice присвоит ей имя текущего активного устройства записи.
domains file=destination goal openwrite(destination, "MYDATA.FIL"), writedevice(OldOut), % Получаем текущее устройство вывода writedevice(destination), % Перенаправляем вывод в файл : : writedevice(OldOut), % Восстанавливаем устройство вывода
domains file=myfile predicates readloop clauses readloop:- readchar(X), X<>'#', !, write(X), readloop. readloop. goal write("This program reads your input and writes it to"),nl, write("tryflie.one. For stop press #"),nl, openwrite(myfile,"tryfile.one") , writedevice(myfile), readloop, closefile(myfile), writedevice(screen), write("Your input has been transferred to the file tryflie.one"), nl.
Домен file имеет три дополнительные опции: stdin, stdout, stderr. Преимущество этих файловых потоков в том, что вы можете переназначить стандартный ввод/вывод в командной строке (таблица 2).
Файловый поток | Описание |
---|---|
stdin | Стандартный ввод является файлом, доступным только для чтения. По умолчанию это клавиатура, readdevice(stdin) назначает устройством ввода stdin |
stdout | Стандартный вывод является файлом, доступным только для записи. По умолчанию это экран терминала, writedevice(stdout) назначает устройством ввода stdout |
stderr | Стандартный вывод ошибок является файлом, который доступен только для записи. По умолчанию это экран терминала. Writedevice(stderr) назначает устройством для вывода сообщений об ошибках stderr |
На следующем шаге мы начнем рассматривать работу с файлами.