Вызовы процедуры wrtfile(F) и wrtfile() обеспечивают переключение с режима writeto(F) на режим writeto('terminal'), где F – путь к принимающему файлу. Данная процедура может использоваться и в теле других процедур, как иллюстрирут следующий пример.
wrtfile := proc(F::{string, symbol}) if nargs = 0 then parse("writeto('terminal');" ', statement') else MkDir(F, 1); parse("writeto(" """ || || F || """ ");" ' || , statement') end if end proc > P:=proc() wrtfile("C:/Temp/test"); parse("read(""C:/Temp/aaa.txt""); A, G, S;", 'statement'); wrtfile() end proc: > P(); readbytes("C:/Temp/Test", 'TEXT', infinity); close("C:/Temp/Test"); "Warning, extra characters at end of parsed string" |
Однако и здесь не все выглядит так радужно, в частности, в таком режиме не сохраня- ются в файле ряд диагностических сообщений, обусловленных ошибочными ситуациями при работе с графическими объектами пакета, а в более общем случае с теми диагностическими сообщениями, которые не отражаются в lasterror-переменной. Именно это не позволяет широко использовать данный подход для их процедурной обработки.
Наконец, по readstat-функции предоставляется возможность считывать Maple-предложения из входного потока, определенного стандартным в момент загрузки ядра пакета.
По умолчанию стандартным полагается ввод с консоли, но это может быть как терминал, так и дисковый файл. После считывания предложения возвращается результат его выполнения. Не останавливаясь детально на данной функции, отметим ее базовый формат кодирования вида readstat({|<Метка>}), по которому вводится без предваряющей метки либо с оной считанное из входного потока Maple-предложение и выполняется, возвращая результат вычисления. Следующий фрагмент иллюстрирует ввод предложений из стандартного входного потока в ответ на вызов readstat-функции:
> V:= 64: G:= 59: S:= 39: Art:= 17: Kr:= 10: readstat(`Common Result: `); [ Common Result: R:= evalf(sqrt(V^2 + G^2 + S^2 + Art^2 + Kr^2)/5, 3); ⇒ 19.5 > readstat(`Multi-line input of Maple-sentence: `); [ Multi-line input of Maple-sentence: evalf( [ Multi-line input of Maple-sentence: sqrt( [ Multi-line input of Maple-sentence: V^2+ [ Multi-line input of Maple-sentence: G^2+ [ Multi-line input of Maple-sentence: S^2+ [ Multi-line input of Maple-sentence: Art^2+ [ Multi-line input of Maple-sentence: Kr^2) [ Multi-line input of Maple-sentence: /5,8); ⇒ 19.480246 > readstat(`Input of two sentences: `); [ Input of two sentences: V:=42.0614: G:=47.07.29: ⇒ 42.0614 Warning, extra characters at end of parsed string > readstat(`Erroneous Input: `); [ Erroneous Input: R:= 10***x+x*Kr(x)+Art(Gamma); syntax error, `*` unexpected: R:= 10***x+x*Kr(x)+Art(Gamma); ^ [ Erroneous Input: R:=10**x+x*Kr(x)+Art(Gamma); ⇒ 10^x + 10 x + 17 |
Примеры фрагмента иллюстрируют как использование ввода с предваряющей меткой, так и без нее. При этом, допускается разбивать ввод на несколько строк, завершая их сборку в одно Maple-предложение по {;|:}-разделителю. Вместе с тем по readstat-функции допустим ввод единственного Maple-предложения и попытка ввода уже двух предложений инициирует ошибочную ситуацию, как это иллюстрирует фрагмент. При этом, не взирая на предупреждающее сообщение, возвращается результат выполнения первого из предложений, независимо от завершающего его {;|:}-разделителя.
В случае попытки ввести неполное Maple-предложение (т.е. не завершенное разделителем {;|:}) readstat-функция запрашивает дополняющий ввод. При обнаружении синтаксической ошибки выводится соответствующее диагностическое сообщение и readstat-функция выводит метку (если она была определена), предлагая повторить ввод. Детальнее с возможностями данной функции можно ознакомиться по справочной системе пакета, что не вызывает каких-либо затруднений. На основе данной функции, определяя в качестве стандартного входного потока файл, можно выполнять записанную в него программу, вызывая ее в рабочую область пакета предложение за предложением.
В отличие от функциональных средств предыдущего раздела, обеспечивающих доступ к внешним файлам данных на уровне логических записей, в качестве которых могут выступать строки или последовательности Maple-выражений, а также целые Maple-предложения, представляемые здесь средства обеспечивают доступ к файлам данных на уровне отдельных символов (байтов). При этом, в отличие от предыдущих средств доступа, данные средства рассматривают все составляющие файл символы однородными, не выделяя в них управляющих типа hex(0D0A)-символов «перевода строки и возврата каретки». Для обеспечения эффективной работы с файлом на уровне отдельных записей-байтов он должен быть определен при открытии как BINARY-файл. Прежде всего, для работы с BINARY-файлами предназначена filepos-функция, рассмотренная в предыдущем разделе. Поддерживающая работу с файлами как TEXT-типа, так и типа BINARY, наибольший смысл она имеет для файлов именно второго типа, т.к. позволяет адресовать указатель на любую позицию файла, содержащую искомый символ (байт). В нижеследующем фрагменте уже первый пример иллюстрирует применение данной функции для определения объемов файлов как текстовых, так и бинарных, в частности загрузочных модулей среды MS DOS и Windows. Эта же функция используется и для идентификации ситуации «конец файла», возвращая на ней нулевое значение. Базовыми же функциями для файлов BINARY-типа являются функции writebytes и readbytes записи и чтения байтов соответственно.
По функции writebytes(<СФ>, <Набор байтов>) производится операция записи в файл, указанный первым фактическим СФ-аргументом (спецификатор или номер приписанного ему логического канала), BINARY-типа набора байтов (символов), определяемого ее вторым фактическим аргументом. В качестве второго фактического аргумента функции могут выступать или Maple-строка (цепочка символов {string, symbol, name}-типа), составляющие символы которой помещаются в принимающий файл в порядке их следования, или список целочисленных значений из [0 .. 255]-интервала, представляющих собой десятичные коды символов из кодовой таблицы ПК, также помещаемых в файл в порядке их перечисления в списке. В частности, для записи байтов с кодами [0 .. 31] можно использовать только вторую форму представления второго фактического аргумента writebytes-функции. В результате успешного завершения операции записи, инициированной функцией writebytes, возвращается число символов (байтов), записанных за операцию в файл.
Если до вызова writebytes-функции принимающий файл был закрыт, то он открывается как файл STREAM-вида в WRITE-режиме доступа, полностью обновляя существующий файл. При этом, тип принимающего файла определяется формой кодирования второго фактического аргумента writebytes-функции следующим образом:
• символьная строка ⇒ TEXT-тип
• целочисленный список ⇒ BINARY-тип
Следующий фрагмент иллюстрирует как данное обстоятельство, так и простой прием конвертации списка hex-значений в список десятичных значений кодов символов, который может быть полезным при практическом программировании, учитывая более привычный способ указания байтов в 16-ричном виде. При этом, относительно стандартных файлов default и terminal функция ведет себя аналогично рассмотренному выше случаю writeline-функции доступа (см. прилож. 3 [12]). Если до применения функции writebytes файл был создан как файл {STREAM|RAW}-вида и затем открыт в режиме READ доступа, то по writebytes-функции он переоткрывается в WRITE-режиме доступа, не изменяя текущей позиции сканирования, т.е. допускается дозапись в файл, начиная с требуемой его позиции. Тогда как его тип определяется согласно вышесказанного в зависимости от формы кодирования второго фактического аргумента функции. Дополнительно к сказанному в следующем фрагменте представлен ряд примеров применения функции writebytes для работы с файлами как TEXT-, так и BINARY-типов, а именно:
> currentdir(`C:/ARM_Book/Academy`): map(filepos, ["Kristo.m", "RANS.99", TRG,
`RAC.REA`, "D:/ Grodno/Maple.doc"], infinity); ⇒ [50896, 250399, 180, 564378, 5149696] > restart; writebytes(`C:/ARM_Book/Academy/Salcombe`,"String of symbols"); ⇒ 17 > writebytes(Salcombe, map(convert, [`80`,`AB`,`A0`,`A4`,`EC`,`A5`,`A2`], decimal, hex)):
> close(Salcombe); readline(Salcombe); ⇒ "Ђ« ¤мҐў"
> writebytes(default, `Набор символов, выводимых на экран монитора`); ⇒ 43 Набор символов, выводимых на экран монитора
Наконец, по readbytes-функции, имеющей следующий формат кодирования: readbytes(<СФ>, { |L|L, TEXT|TEXT})
возвращается заданное фактическим L-аргументом функции количество байтов/символов, считанных, начиная с текущей (сканируемой) позиции файла, указанного первым фактическим СФ-аргументом (спецификатор или номер приписанного ему логического канала) функции. В случае отсутствия L-аргумента (целого положительного числа либо infinityзначения) считывается единственный байт, расположенный в сканируемой позиции файла. В случае указания для L-аргумента infinity-значения считываются все байты, расположенные между сканируемой позицией и концом файла. При определении TEXT-аргумента возвращаемые readbytes-функцией байты представляются строчной структурой, в противном случае – в виде списка значений своих десятичных кодов.
При этом, если при вызове readbytes-функции определен TEXT-аргумент, то операция чтения завершается либо по достижении нулевого байта, либо исчерпания указанного L-аргументом количества байтов. Если же в файле содержится либо остается меньшее число байтов, чем определено L-аргументом при вызове readbytes-функции, то все они считываются; при пустом остатке функция возвращает нулевое значение (т. е. обнаружена ситуация «конец файла»), а сам файл автоматически закрывается, если в качестве фактического СФ-аргумента функции был указан спецификатор файла. Однако, если определенный СФ-аргументом readbytes-функции файл закрыт, он открывается в READ-режиме как файл STREAM-вида и его тип определяется в зависимости от наличия TEXTаргумента аналогично случая writebytes-функции, рассмотренной выше. Для работы с BINARY-файлами нами разработан ряд полезных процедур [41,103], например, statfпроцедура поизводит анализ открытых файлов относительно типов TEXT и BINARY.