![]() |
|
Главная Терминология Хоора 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [ 17 ] 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 д^а операция используется для инициации процесса чте-, jjjjH последовательности. \ 1ереход к следующей компоненте. Операция li get{x) (1.50) означает одновременные присваивания -- Хл:-=-ге8({хк) ---. , х\ first {rest (xi) Заметим, что first {s) определено только при s < >. f Операции rewrite и reset не зависят от позиции буфера иайла перед их выполнением. В любом случае они возвра-I щают его к началу файла. I, При просмотре последовательности необходимо иметь воз-* ложность распознавать ее конец, поскольку при достижении (конца последовательности операция j х\ х= first {xid становится неопределенной. Достижение конца файла, оче-i видно, равнозначно тому, что правая часть xr пуста. Поэтому мы вводим предикат eof{x) = XR = { ) . (1.51) который означает, что достигнут конец файла (end of file). Следовательно, операция get{x) может выполняться только при eof{x) = false. В принципе все действия с файлами можно выразить с помощью четырех основных файловых операций. На практике же часто бывает естественно объединять операции продвижения по файлу (get или put) с обращением к буферной переменной. Поэтому мы введем еще две процедуры, которые можно выразить в терминах основных операций. Пусть v - Переменная, а е - выражение базового типа То файла. Тогда read{x, v) эквивалентно v:=xt; get(x) а write (х, е) эквивалентно xt :=; ри1{х) %еимущество использования read и write вместо get и put язано не только с краткостью, но и с простотой концепции, поскольку теперь можно игнорировать существование буферной переменной xf, значение которой может быть и не- Ределенным. Однако буферная переменная бывает полезна я заглядывания вперед . 1. Фунааментльные структуры аанных Для выполнения этих двух процедур необходимы спеАу\ щие условия: -.eof{x) для read(x, v) eofix) для write (х, е) При чтении файла предикат eof{x) становится истинным, кац только прочитана последняя компонента файла х. На это^ основаны две схемы программ для последовательного фор, мирования и обработки файла х. Дополнительными парамет. рами в этих схемах являются операторы R и S и предикат д Запись файла х:
(1.52) 1.11.2. Файлы CO сложной структурой При решении многих прикладных задач необходим! в большие файлы ввести некоторую подструктуру. Например, книга, хотя и может рассматриваться как единая последовательность букв, подразделяется на главы и абзацы. Назначение подструктуры - задание неких явных точек отсчета некоторых координат, которые позволят легче ориентире ваться в длинной последовательности информации. Суше ствующие запоминающие устройства часто дают определен ные средства для представления таких точек отсчета (напри мер, маркеры магнитной ленты) и позволяют находить их е' скоростью большей, чем скорость просмотра информаШ между этими точками. В рамках принятой нами системы обозначений естествен ный способ ввести первый уровень подструктуры - это ра сматривать подобный файл как последовательность элемеН тов, которые в свою очередь являются последовательностям аг. е. как файл файлов. Предположим, что конечные элемент' f, *) Слово сегмент встречается, пожалуй, только в этой книге,- Рим. ред. единицы принадлежат к типу U, тогда подструктуры LnVT типа gecb файл -типа Очевидно, что таким образом можно строить файлы с любым уровнем вложенности. В общем виде тип Т„ можно определить с помощью рекурсивного соотнощения Ti = meofTi i, i=l..n g = и. Такие файлы часто называют многоуровневыми файлами, а компоненту типа Ti называют сегментом* i-ro фовня. Примером многоуровневого файла является книга, в которой уровням сегментации соответствуют главы, разделы, абзацы и строки. Но наиболее общий случай - эго файл с одним уровнем сегментации. Такой файл, сегментированный на одном уровне, никоим образом не идентичен массиву файлов. Прежде всего число сегментов файла может меняться, и файл по-прежнему может увеличиваться только с конца. В рамках введенных выше обозначений и при определении файла как х: Ше of file oiU х\ будет обозначать доступный в текущий момент сегмент, а xff-доступную в текущий момент единичную компоненту. Соответственно put{x\) и ge.t{xj) ссылаются на единичную компоненту, а put(x) и get(x) означают операции добавления очередного сегмента и перехода на очередной сегмент. Сегментированные файлы удовлетворительно реализуются практически на всех запоминающих устройствах с последовательным доступом, включая ленты. Сегментация не меняет их важнейшего свойства - последовательного доступа либо к отдельным компонентам, либо (возможно, при помощи более быстрого механизма пропуска) к сегментам. Другие запоминающие устройства, а именно магнитные барабаны и диски, обычно содержат некоторое количество до-Рожек, каждая из которых представляет собой запоминающее устройство с последовательным доступом, но которое обычно слишком мало, чтобы вместить целый файл. Таким Образом, на дисках файлы обычно- распределяются на несколько дорожек и содержат соответствующую библиотечную информацию, связывающую эти дорожки. Очевидно, что |