Потоки и файлы
Система Mathematica имеет развитые средства для работы с потоками (streams) и файлами (files). Под потоком подразумевается непрерывная последовательность данных, циркулирующих внутри компьютера. Обмен потоками происходит практически непрерывно, например, при вводе поток ввода поступает от клавиатуры в компьютер, при печати поток данных поступает от компьютера в принтер через порт принтера и т. д.
Файлом является упорядоченная структура данных, имеющая имя и хранящаяся на каком-либо носителе, чаще всего на магнитном диске. Файлы могут иметь различные форматы и различный тип доступа к хранимой на них информации. Наиболее распространенные в системе Mathematica файлы документов являются файлами с последовательным доступом и имеют текстовый формат.
Последовательный доступ означает, что информация из открытого файла может быть считана строго последовательно от его начала до конца, отмеченного специальной меткой. Это напоминает считывание с магнитофонной кассеты. Текстовый формат означает, что все данные записаны в виде ASCII-кодов. Следовательно, прочесть такой файл можно с помощью любого текстового редактора, работающего с текстами в виде ASCII-кодов.
Потоки и файлы имеют много общего: имена, определенную структуру, необходимость открытия перед использованием и закрытия после использования. Однако если с файлами пользователь сталкивается уже в начале работы с системой (нужно вызвать файл с демонстрационным документом или сохранить его, а затем вызвать другой файл), то с понятием потока при работе с системой сталкиваться практически не приходится, хотя помимо нашей воли потоки данных постоянно текут между компьютером и его периферийным оборудованием.
Прежде чем рассматривать весьма обширные возможности системы по работе с файлами в целом, отметим упрощенный прием вызова файла с помощью двойного символа «<<»:
<<filename
Эта команда считывает файл с указанным именем filename и заносит в память компьютера содержащиеся в нем определения. Имя файла надо указывать полностью, то есть вместе с расширением. Исключением является случай, когда файл находится в основном каталоге системы. Эта команда эквивалентна функции
Get["filename", key]
Для записи объекта (переменной, массива, списка и т. д.) в файл служат упрощенные команды:
Указанные команды по существу есть укороченные (и потому более удобные) формы следующих функций:
Еще одна упрощенная функция — ! ! filename — выводит содержимое файла с заданным именем.
Следующие примеры показывают запись списка в файл C:\ma.vat, его считывание, затем добавление в файл еще одного списка и контроль контекста файла:
{{l,2,3},{4,5,6},{a,b,c}}>>C:\ma.val
<<С: \ma. val
{{1, 2, 3}, {4, 5, б), {а, b, с}} {d,e,f}>>>C: \ma.val
<<С: \та. val
{d, e, f}
!!С:\mа.val
1, 2, 3, 4, 5, б, а, b, с d, e, f
Такая форма вызова особенно удобна для вызова файлов пакетов расширений и применений системы. Имя файла указывается по правилам, принятым в MS-DOS. Файлы пакетов применений имеют расширение .т. Мы уже приводили примеры использования определений, содержащихся в файлах пакетов расширения системы.
Имеется еще ряд функций для работы с файлами:
Допустим, что в любом текстовом редакторе создан файл с полным именем C:\datas.txt в ASCII-формате, содержащий просто шесть чисел с разделительными пробелами, размещенные в двух строках и представляющие массив 2x3 элемента:
1 11.2 34.5
2. 3.4 56
Тогда о структуре файла можно судить, используя команду
!!С:\datas.txt
1 1.2 34.5 2. 3.4 56.
Нетрудно заметить, что структура файла соответствует структуре массива. Однако считывание файла командой «name дает следующий результат:
<<С: \datas. txt
380.8
Результат представляет вычисленное выражение второй строки файла. Считывание функцией ReadList без дополнительного аргумента также дает ошибочный результат:
ReadList["С:\datas.txt"]
{41.4, 380.8}
Нетрудно подметить, что функция восприняла каждую строку содержимого файла как результат перемножения трех чисел (пробел на языке Mathematica означает умножение). С дополнительным параметром Number все числа считываются верно:
ReadList["С:\datas.txt", Number]
{1, 1.2, 34.5, 2., 3.4, 56.}
Однако мы получили одномерный список — данные просто считываются построчно. Применение дополнительного параметра в виде {Number, Number} дает следующий результат:
ReadList["С:.txt", {Number, Number}]
{{1, 1.2), {34.5, 2.}, {3.4, 56.}}
Правильный результат можно получить, используя опцию RecordList->True: .
ReadList["C:.txt",Number,RecordLists-XTrue]
{{1, 1.2, 34.5), {2., 3.4, 56.}}
Для загрузки файлов пакетов расширений (Add-On) используются функции, позволяющие задать контекст файлов (подробнее о контекстах речь пойдет в уроке 10):
Загрузка файлов с указанием их контекстов позволяет избежать конфликтов между разными пакетами расширения, используемыми одновременно (см. более подробно урок 10).