Что такое логический файл
Файл - последовательность однотипных компонентов, ограниченная специальным признаком - конец файла, расположенная на внешнем устройстве. Одновременно с файлом в оперативной памяти выделяется участок, по размеру совпадающий с одним компонентом файла, называемый буфером или окном файла. Вся работа с файлом производится через этот буфер.
По структуре - файл есть последовательность элементов. Принято компонент файла называть записью (это сложилось исторически до появления языка Паскаль). Необходимо отличать понятия запись в файле от записи, как типа данных в Паскале. Запись в файле - достигнутый компонент при выполнении операции чтении из файла или операции записи в файл. Размер записи (компонента файла) в файле определяется типом компонента файла.
При определении переменной типа файл мы определяем две структуры - структуру на внешнем устройстве и структуру в оперативной памяти (рис. 24.1)
Структура на внешнем устройстве представляет собой последовательность однотипных компонентов, ограниченную признаком конец файла. Для связи переменной типа файл с конкретным внешним устройством задаются специальные команды.
Структура в оперативной памяти - буфер или окно файла, размером в один компонент файла. Все общение с файлом, расположенном на внешнем устройстве, осуществляется через буфер файла, который находится в оперативной памяти.
Рис. 24.1. – Структурная организация данных типа файл
0. Определение типа
Для того, чтобы определить тип файл необходимо определить тип элементов, которые могут входить в файл. Количество компонентов не определяется. Типом компонентов может быть любой, кроме файлового, тип. Непосредственное определение типа файл приведено на рис. 24.2.
Рис. 24.2. – Определение типа файл
Как всегда, это определение делается в разделе нестандартных типов. Однако язык позволяет не определять тип компонента файла. В этом случае в качестве типа данных указывается тип FILE (такой файловый тип называется нетипизированным). Для нетипизированного файла нельзя выполнять стандартные операции по чтению и записи.
Примеры определения файловых типов и файлов:
tf1=file of integer;
tf2=file of real;
В этих примерах f1 – файл из целых чисел, f2 – файл из вещественных чисел, f3 - нетипизированный файл. С файлом f3 нельзя выполнять стандартные операции по чтению и записи.
1. Множество значений
Включает в себя все значения, которые могут быть размещены в структуре, заданной определением типа.
2. Множество операций
Все операции с переменными типа файл (в дальнейшем будем говорить - с файлом) сводятся к двум: запись в файл и чтение из файла. Правила выполнения этих операций зависят от вида файлов. Виды файлов определяются техническими возможностями внешних устройств, на которых располагаются файлы.
Физические и логические файлы
Для независимости программы обработки файлов от конкретной операционной системы один и тот же обрабатываемый файл одновременно является физическим и логическим.
Логический файл – это имя переменной файлового типа в программе. Выполнение операторов программы по обработке файла осуществляется посредством этой переменной. Переменная файлового типа в программе называется именем логического файла.
Физический файл – это файл, определенный по правилам конкретной операционной системы. В любой операционной системе файл определяется как поименованная порция информации, расположенная на внешнем устройстве. Это имя называется именем физического файла.
Во всех операционных системах, применяемых для ПЭВМ типа IBM, не дисковые файлы именуются именами внешних устройств, на которых они располагаются. Обязательные внешние устройства имеют свои уникальные имена (CON – клавиатура при чтении-вводе и экран дисплея при записи-выводе, PRN – принтер и др.). Дополнительные (факультативные) внешние устройства именуются именами портов ввода-вывода, к которым они подключены (LPT1, LPT2, LPT3, COM1, COM2, COM3 и т.д.). Так как обычно принтер подключается к первому параллельному порту, имена PRN и LPT1 являются синонимами.
Имена дисковых файлов состоят из имен дисковода, на котором они расположены, имен каталогов-папок, в которые они вложены и из полных имен файлов (составные части разделяются обратными слэшами \). Например, С:\TP60\WORK\dan.dat – имя физического файла, расположенного на диске С:, вложенного внутрь каталога ТР60, подкаталолга WORK, полное имя этого файла dan.dat.
Для того чтобы программа обрабатывала реальный файл, до начала обработки файла обязательно логическому файлу в программе сопоставляется физический файл в операционной системе. Это называется связыванием логического и физического файлов.
Связывание осуществляется с помощью стандартной процедуры assign, имеющей два параметра. Первый параметр – имя логического файла. Второй параметр – строка символов с именем физического файла, заданного по правилам конкретной операционной системы.
Современные ЭВМ имеют в своём составе внешние запоминающие устройства, способные хранить огромные массивы информации в течение сколь угодно длительного времени. Наиболее удобным местом хранения является дисковая память, которой оснащены все персональные компьютеры (ПК). Дисковая память – это место хранения данных, не используемых в данный момент для алгоритмической обработки. На диске хранятся как программы, системные и пользовательские, так и данные различного назначения.
Любая информация, хранимая во внешней памяти ЭВМ, независимо от назначения этой информации, организуется как файл.
Файлы называют внешними структурами данных в отличие от всех остальных структур данных, хранимых в основной памяти только на время работы программы и называемых оперативными.
В общем смысле под файлом понимают любое внешнее устройство, способное хранить (или создавать) информацию в форме, воспринимаемой ЭВМ: клавиатура дисплея, экран дисплея, магнитная лента, перфолента, печатающее устройство, магнитные диски и т.п.
С точки зрения хранения информации на дисках файл – это поименованная область памяти на диске, в которой хранится логически однородная информация.
В дальнейшем изложении будем ориентироваться на дисковую память ПК.
СТРУКТУРА ФАЙЛА
Методы организации и обработки файлов как данных, располагаемых во внешней памяти, имеют ряд особенностей по сравнению со способами организации и обработки оперативных структур данных.
Напомним, что алгоритмическая обработка выполняется только над данными, размещёнными в основной памяти.
Поэтому данные, находящиеся во внешней памяти и подлежащие обработке, должны быть сначала перемещены в основную память. Как правило, это перемещение данных из внешней памяти в основную и в обратном направлении осуществляется небольшими порциями (файл не может полностью уместиться в основной памяти). Следовательно, файл должен быть определённым образом структурирован.
Наиболее всеобщей формой структурирования информации является последовательность. Последовательность имеет удобную и эффективную реализацию на всех запоминающих устройствах.
Файл представляет собой последовательность компонент одного типа.
В последовательности определяется некоторый естественный порядок компонент. В любой момент непосредственно доступна только одна компонента. Её можно либо «просматривать», либо «формировать»; одновременно делать то и другое невозможно. К остальным компонентам можно «прийти», лишь двигаясь шаг за шагом вдоль файла. Файл формируется путём последовательных добавлений в его конец новых компонент. Поэтому определение файлового типа не задаёт число компонент.
ПОНЯТИЕ МЕТОДА ДОСТУПА
Вся деятельность СУФ базируется на фундаментальном понятии метода доступа. Метод доступа – совокупность программного способа доступа к данным и метода организации данных.
В основе современных методов организации файлов лежит последовательный метод, принятый в системе Турбо Паскаль. На рис.3 показана схема последовательного файла с иллюстрацией соответствующей терминологии.
В дальнейшем будем рассматривать логический файл, т.к. на него ориентирована алгоритмическая обработка.
Объявление файловой переменной в программе связано с выделением в оперативной памяти специальной, скрытой от нас переменной, значение которой равно номеру логической компоненты файла, «видимой» операционной системе в данный момент времени обработки файла. Эта переменная называется указателем текущей компоненты. На рисунках указатель изображается стрелкой. СУФ автоматически нумерует все компоненты, начиная с нуля.
Компонента, номер которой хранит указатель, называется текущей. Если указатель показывает на компоненту i, то компонента с номером i-1 называется предыдущей, а с номером i+1 – последующей по отношению к текущей компоненте.
Последовательная организация файла предусматривает запись компонент в файл, начиная с нулевой компоненты; затем записывается первая, затем вторая и т.д. компоненты.
Последовательный доступ к файлу предусматривает обработку записей файла по правилу, соответствующему упорядочению: после обработки компоненты с номером i, автоматически становится доступной компонента с номером i+1. Обработка начинается с нулевой компоненты.
Магнитные диски позволяют организовать, наряду с последовательным, прямой доступ к любой логической компоненте. Всякий раз, когда необходимо обратиться к некоторой компоненте, программа сообщает конкретный номер этой компоненты (т.е. устанавливает указатель на соответствующую компоненту, независимо от того, какая компонента до этого была обработана). СУФ имеет специальные процедуры прямого доступа, к которым обращается программа.
Таким образом, Турбо Паскаль предусматривает последовательную организацию информации в файле с последовательным и прямым доступом к компоненте файла.
ОТКРЫТИЕ И ЗАКРЫТИЕ ФАЙЛА.
Устройство внешней памяти хранит большое количество файлов. Естественно, программа должна сообщить СУФ, с каким конкретным файлом (файлами) она будет работать. Для этого в СУФ предусмотрена процедура открытия файлов. Открытие файла предусматривает указание начальной метки файла и направление обмена информацией: если файл формируется, он открывается для записи; если файловая информация используется в алгоритме или файл модифицируется, он открывается для чтения. При открытии файла СУФ автоматически нумерует записи файла, создаёт указатель текущей записи, устанавливает его на нулевую компоненту, выделяет буфер.
Если обработка файла закончена, необходимо его закрыть. Закрыть файл – это, прежде всего, высвободить буфер. Если файл только что сформирован, при закрытии ставится метка номера файла. СУФ имеет специальную процедуру «закрыть файл». После закрытия файл «исчезает» из области видимости СУФ.
ФОРМИРОВАНИЕ ФАЙЛА
Формирование файла связано с алгоритмом создания логической компоненты файла и записью (перемещением) этой информации на диск.
Очевидно, что в программе должна быть объявлена некоторая переменная оперативной памяти, тип которой идентичен (совпадает) с типом файловой компоненты. В соответствии с постановкой задачи в программе определяется значение этой переменной. Для перемещения информации в файл используется знакомая нам операция
WRITE (<имя файл. перем.>, <имя логич. комп.>);
Напоминаем, что файл должен быть предварительно открыт для записи.
Например, если компоненты файла – целые числа, то объявим логическую компоненту как переменную целого типа:
h : file of integer;
Так как все компоненты файла имеют одинаковый тип, очевидно, что формирование файла необходимо вести в цикле. Но логический файл не имеет конечной длины. Как правило, наиболее общим алгоритмом формирования файла является цикл-пока. Условием окончания цикла является задание некоторого значения-сигнала. Это значение не записывается в файл и никогда в файле не встречается. Оно задаётся константой того же типа, что и тип компоненты.
Структура алгоритма создания файла показана рис.4. S – некоторое сигнальное значение.
Например, необходимо записать в файл информацию о студентах по следующим спецификациям:
фамилия, номер зачётной книжки, номер группы. Студенты не «рассортированы» по группам. Соответствующая программа приведена на рис.5.
VAR h : file of SR;
writeln(‘введите номер группы очередного студента’);
writeln(‘0 – признак окончания ввода’);
while a.numbG<>0 do
writeln(‘введите номер группы очередного студента’);
writeln(‘Запись файла окончена’);
Рис .5
В этой программе роль сигнальной переменной играет константа целого типа нуль, записанная в условие проверки при входе в цикл while. Такое значение выбрано из соображения, что, как правило, не бывает номера группы нуль.
В строках 1, 2, 4 набираются значения полей структурированной логической компоненты a. Тип её объявлен одинаковым с типом компоненты файла h. Как только значение номера группы введётся нулевым, цикл формирования файла заканчивается. Процедура закрытия файла в конце формирования создаёт метку конца файла на диске.
ЧТЕНИЕ И МОДИФИКАЦИЯ ФАЙЛА
Файл читается, прежде всего, для проверки созданной информации, а также для алгоритмической обработки в соответствии с условием задачи. Чтение возможно только для сформированного файла!
После чтения последней компоненты указатель текущей записи переместится на метку конца файла. Попытка читать файл в таком состоянии приведёт к аварии в программе. Для слежения за ситуацией «наступил конец файла» СУФ имеет логическую функцию
EOF(<имя файлов. перем.>).
Значение этой функции есть FALSE, если указатель стоит на любой существующей компоненте файла, и TRUE, если указатель переместился на метку конца файла.
Чтение очередной компоненты файла выполняется с помощью обращения к процедуре
READ (<имя файл. перем.>,<имя логич. комп.>)
Второй параметр процедуры чтения имеет тот же смысл, что и п.2.3.
Наиболее общий алгоритм чтения и обработки информации из файла изображён на рис.6. Это алгоритм последовательного доступа.
Шаг «обработать компоненту» может быть алгоритмически простым (например, печать компоненты), а может представляться сложным алгоритмом в соответствии с условием задачи.
В качестве примера продолжим программу на рис.5 фрагментом программы распечатки созданного файла. Для этого строку отодвинем в конец модифицированной программы. Продолжение программы приведено на рис.7.
while not EOF(h) do
Рис.7
Примеры решения задач на обработку файлов
Пример 1.
Создать файл, состоящий из последовательности чисел целого типа. Вычислить среднее арифметическое квадратов нечётных компонент файла. Исходный файл распечатать.
K=4; K – количество нечётных компонент в файле f.
; SR – среднее арифметическое нечётных компонент.
Блок-схема алгоритма приведена на рис.8.
Шаги основного проекта алгоритма пояснены в предыдущих параграфах и не требуют детализации в виде блок-схемы.
Программа на языке Турбо Паскаль приведена на рис.9.
TYPE FAL=file of integer;
а – компонента логического файла>
writeln(‘Введите имя файла: ‘);
writeln(‘Признак конца ввода – 999’);
writeln(‘Вводите очередное целое число’);
Writeln(‘Вводите очередное целое число’);
while not EOF(f) do
while not EOF(f) do
if (a mod 2)<>0 then
writeln(‘ср. ар. = ’,SR:6:2)
Рис.9
Даны символьные файлы f1 и f2. Переписать с сохранением порядка следования компоненты файла f1 в файл f2, а компоненты файла f2 - в файл f1. Вспомогательный файл не использовать. Блок-схема основного проекта приведена на рис.10.
Программа алгоритма обмена содержимым символьных файлов f1 и f2 приведена на рис.11.
f1,f2 : file of char;
write(‘Пиши в файл f1 символы’);
writeln(‘Признак конца ввода - *’);
write(‘Пиши в файл f2 цепочку символов’);
writeln(‘Признак конца ввода - *’);
writeln(‘Файлы: f1, f2 созданы’);
while(not eof(f1)) and (not eof(f2)) do
компоненту >
while not eof(f1) do
while not eof(f2) do
writeln(‘Файл f1 после обмена’);
while not eof(f1) do
writeln(‘Файл f2 после обмена’);
while not eof(f1) do
Рис.11
В тестовой матрице вторая строка должна быть переписана в файл f. Очевидно, файл не будет сформирован, если в каждой строке матрицы встретится хотя бы один нуль.
Блок-схема основного проекта приведена на рис.12.
На рис.13 показана последовательная обработка строк:
kF – переменная-флажок, сигнализирующая, что хотя бы одна строка в файл будет записана (kF=1);
i – номер обрабатываемой очередной строки;
j – текущий номер элемента в строке;
ki – переменная-флажок: ki=0, если нет ни одного нулевого элемента в строке; ki=1, если есть хотя бы один нуль в строке.
N – количество столбцов матрицы, M – количество строк матрицы.
Остальные шаги на рис.12 не требуют детализации. Программа алгоритма задачи приведена на рис.14.
A : array [1..M1,1..N1] of integer;
f : file of integer;
writeln(‘Введите M – кол. строк матр., N – кол. столбцов’);
writeln(‘Введите матрицу строками’);
не содержащие нулей, записываем в файл f >
while not EOF (f) do
writeln(‘файл не сформирован’);
Рис.14
ФАЙЛЫ
Основные понятия, связанные с организацией файлов
Современные ЭВМ имеют в своём составе внешние запоминающие устройства, способные хранить огромные массивы информации в течение сколь угодно длительного времени. Наиболее удобным местом хранения является дисковая память, которой оснащены все персональные компьютеры (ПК). Дисковая память – это место хранения данных, не используемых в данный момент для алгоритмической обработки. На диске хранятся как программы, системные и пользовательские, так и данные различного назначения.
Любая информация, хранимая во внешней памяти ЭВМ, независимо от назначения этой информации, организуется как файл.
Файлы называют внешними структурами данных в отличие от всех остальных структур данных, хранимых в основной памяти только на время работы программы и называемых оперативными.
В общем смысле под файлом понимают любое внешнее устройство, способное хранить (или создавать) информацию в форме, воспринимаемой ЭВМ: клавиатура дисплея, экран дисплея, магнитная лента, перфолента, печатающее устройство, магнитные диски и т.п.
С точки зрения хранения информации на дисках файл – это поименованная область памяти на диске, в которой хранится логически однородная информация.
В дальнейшем изложении будем ориентироваться на дисковую память ПК.
СТРУКТУРА ФАЙЛА
Методы организации и обработки файлов как данных, располагаемых во внешней памяти, имеют ряд особенностей по сравнению со способами организации и обработки оперативных структур данных.
Напомним, что алгоритмическая обработка выполняется только над данными, размещёнными в основной памяти.
Поэтому данные, находящиеся во внешней памяти и подлежащие обработке, должны быть сначала перемещены в основную память. Как правило, это перемещение данных из внешней памяти в основную и в обратном направлении осуществляется небольшими порциями (файл не может полностью уместиться в основной памяти). Следовательно, файл должен быть определённым образом структурирован.
Наиболее всеобщей формой структурирования информации является последовательность. Последовательность имеет удобную и эффективную реализацию на всех запоминающих устройствах.
Файл представляет собой последовательность компонент одного типа.
В последовательности определяется некоторый естественный порядок компонент. В любой момент непосредственно доступна только одна компонента. Её можно либо «просматривать», либо «формировать»; одновременно делать то и другое невозможно. К остальным компонентам можно «прийти», лишь двигаясь шаг за шагом вдоль файла. Файл формируется путём последовательных добавлений в его конец новых компонент. Поэтому определение файлового типа не задаёт число компонент.
ФИЗИЧЕСКИЙ И ЛОГИЧЕСКИЙ ФАЙЛЫ
Особенности устройств внешней памяти, на которых хранится файл, и основной памяти, где файл создаётся, а затем обрабатывается, заставляют рассматривать файл с двух позиций: как логическую, т.е. абстрактную (программную) структуру данных, и как реальную, физическую структуру данных, размещённую на конкретном носителе. В соответствии с указанными точками зрения существуют понятия «логический файл» и «физический файл».
Переменную, объявленную в программе как файл с определённой структурой компонент, соответствующей структуре любого оперативного типа данных (примитивы, массивы, записи и т.п.), называют логическим файлом. Логическая организация файла определяется пользователем на основе требований задачи.
Поименованные данные, хранимые на устройстве внешней памяти в виде последовательности физических групп информации (блоков информации), участвующих в операциях пересылки между основной и внешней памятью, называют физическим файлом.
Соответствие между физическим и логическим файлами реализуется системными программами, составляющими систему управления файлами (СУФ). Всякое действие, определяемое программой пользователя (алгоритмом), интерпретируется СУФ некоторой совокупностью действий на физическом уровне.
На рис.1 показано соответствие между физическим и логическим файлами.4
Представление физического файла тесно связано с характеристиками конкретного устройства внешней памяти. На магнитном диске физический файл представляет собой цепочку бит, рассоложенных по концентрическим дорожкам (трекам) на магнитной поверхности. Места расположения треков получаются при специальной подготовке диска (форматировании). Цепочки бит разделяются на подцепочки, называемые физическими записями (физическими компонентами), или блоками. Каждый блок физического файла содержит определённое число компонент логического файла. Это число называется коэффициентом блокирования и устанавливается СУФ либо по умолчанию (стандартно), либо по указанию пользователя.
На рис.1а физические записи разделены свободными от информации промежутками (заштрихованные промежутки), величина которых зависит от точности работы аппаратуры управления процессом считывания и записи информации. Заштрихованные области в начале и конце схемы физического файла называются метками файла. По начальной метке файл отыскивается среди множества всех файлов на диске. Конечная метка позволяет СУФ определять последний блок в данном файле.
Из рис. 1а, 1б видим, что коэффициент блокирования для рассматриваемого файла равен двум. На рис.1в показан один из возможных вариантов структуры компоненты логического файла. Например, если рассматривается файл с информацией о книгах, хранимых в некоторой библиотеке, структура компоненты соответствующего логического файла может быть, например, такой:
название (строка символов);
автор (строка символов);
издатель (строка символов);
год (целое число);
стоимость (вещественное число).
В любом случае методы логической организации файлов (представление данных, реализация функций доступа) являются прямым применением оперативных структур данных: примитивов, массивов, записей RECORD, списков и т.п.
Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого.
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰).
Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначенные для поддерживания проводов на необходимой высоте над землей, водой.
В этом разделе мы рассмотрим различные компоненты базы данных AS/400. Я не ставил здесь перед собой задачу проинструктировать Вас, как использовать эту базу данных. Уже есть целый ряд хороших книг, посвященных внешним аспектам базы данных и использованию двух ее интерфейсов в программах 7 Моя любимая книга на эту тему — Paul Conte. Database Design and Programming for DB2/400. Duke Press .1997. Настоятельно рекомендую! . А я лишь хочу предложить Вам обзор характеристик СУБД и основ ее функционирования.
Раздел состоит из двух частей. В первой содержится описание основных функций, которые должны присутствовать в каждой СУБД , и их реализации в AS/400. Во второй — обзор других характеристик базы данных , некоторые из которых имеют отношение к производительности, а другие обеспечивают поддержку использования AS/400 в качестве сервера базы данных . После этого мы поговорим о внутренней реализации некоторых фундаментальных функций базы данных .
Функции СУБД
Есть много способов реализации реляционной базы данных, но любая система управления ею должна предоставлять следующие семь функций:
- определение и описание таблиц базы данных;
- операции управления данными (вставка, выборка, обновление и удаление);
- возможность определить, что представляют собой данные независимо от программы;
- возможность создавать новые проекции данных для удовлетворения изменяющихся требований прикладных программ;
- множественные проекции данных для разных прикладных программ;
- защита данных;
- целостность данных.
Теперь посмотрим, как эти функции реализованы в AS/400.
Описание данных и создание файлов
Для описания физических и логических файлов базы данных можно использовать "родной" язык СУБД AS/400 — DDS . Он содержит операторы, ключевые слова и параметры, позволяющие описывать как атрибуты самого файла, так и полей записей базы данных. DDS можно также применять для описания файлов устройств , используемых AS/400. Эти файлы устройств содержат информацию о формате и типах данных, используемых подключенными к системе физическими устройствами.
DDS позволяет определить несколько атрибутов полей записей базы данных. Среди них имя поля, его длина и род данных (текстовые или числовые). В зависимости от типа данных поля можно задать некоторые другие специфические атрибуты. Например, если поле содержит десятичные данные, можно задать общее число десятичных цифр и число цифр справа от запятой.
Операторы DDS помещаются в разделах исходных файлов, которые затем превращаются в файловые объекты с помощью команд OS/400 "CRTPF" ("Create Physical File") и "CRTLF" ("Create Logical File"). Для описания атрибутов файлов базы данных можно использовать и SQL. В отличие от DDS , представляющего собой только язык описания данных, один оператор SQL и описывает, и создает таблицы и проекции (view). В SQL определение файла неотделимо от команды создания. Например, оператор SQL "Create table" задает имя таблицы, имена столбцов (полей) и их атрибуты. Кроме того, при исполнении этого оператора создается и сама таблица.
Создание физических файлов и таблиц
Физические файлы или, в терминологии SQL, таблицы содержат собственно данные. Запись физического файла имеет фиксированный набор полей. Каждое поле может иметь (хотя и не часто) переменную длину. В терминологии SQL таблица содержит строки фиксированной длины со столбцами переменной длины 8 Чтобы избежать полной путаницы, я использую, где возможно, более привычную для пользователей AS/400 терминологию "родного" интерфейса, за исключением случаев, когда описывает ся реализация именно SQL. .
Физический файл состоит из двух частей. В первой находятся атрибуты файла и описания полей . В набор атрибутов файла входят его имя, владелец, размер, число записей, ключевые поля и некоторые другие характеристики. Описания полей задают атрибуты для каждого поля записей.
Вторая часть физического файла содержит собственно данные. Она может состоять из одного или нескольких разделов, позволяющих подразделять файл. Все записи во всех разделах обязательно имеют один и тот же формат. Это удобный способ разделения записей: например, информацию текущего месяца можно поместить в один раздел, а информацию прошлого — в другой. Каждый раздел имеет уникальное имя, которое можно использовать для доступа к записям. Таблицы SQL могут состоять только из одного раздела, что соответствует самой сути реляционной модели: все данные хранятся в двумерных таблицах. Файлы же имеющие несколько разделов — трехмерные.
Для создания физического файла используется системная команда "CRTPF". Она создает физический файл по операторам из исходного файла. Вновь созданный физический файл не содержит записей данных, для их добавления необходимо использовать отдельную программу или утилиту.
Как было отмечено ранее, оператор определения данных SQL также создает таблицу. Оператор "Create table" можно выполнить с помощью Query Manager, Interactive SQL , или вставив его в программу на ЯВУ . Таблица, созданная этим оператором, является физическим файлом, идентичным созданному с помощью "родного" интерфейса.
Создание логических файлов и проекций
Логические файлы дают возможность доступа к данным в формате, отличном от использующегося для их хранения в одном или нескольких физических файлах. Логические файлы обеспечивают независимость данных и программ, которая будет обсуждаться в следующем разделе. Они не содержат записей данных, а лишь относительный номер записи (индекс) данных в физическом файле. Часто говорят, что логический файл задает путь доступа к данным.
Структура логического файла может быть как очень простой, так и очень сложной. Логические файлы и проекции можно подразделить на четыре категории. Перечислю их.
- Простые логические файлы и проекции, которые отображают данные из одного физического файла или таблицы на другое описание логических записей.
- Многоформатные логические файлы , обеспечивающие доступ к нескольким физическим файлам, каждый из которых имеет собственный формат записей. Данный тип логического файла может быть создан только с помощью "родного" интерфейса; с помощью SQL его создать нельзя.
- Логические файлы объединения (join), задающие одно определение логической записи, построенное из любой комбинации полей двух или более физических файлов, таблиц, логических файлов или проекций. При этом общее число физических файлов и таблиц не должно превышать 32.
- Проекции SQL (view), которые похожи на логические файлы объединения и дают те же результаты, но реализованы совершенно иначе. Файлы объединения хранят путь доступа для каждого объединения. Проекции же SQL определяют пути доступа во время исполнения, руководствуясь хранящимся внутри шаблоном определения запроса (Query Definition Template).
Подобно физическому, логический файл состоит из двух частей. Первая — точно такая же, как и у физического файла. Она содержит атрибуты файла и описания полей . Вторая часть содержит относительные номера записей данных физического файла. Программе, использующей логический файл , видимы только те данные физического файла, которые соответствуют описанию полей логического файла .
Для создания логического файла используется системная команда "CRTLF". Она использует операторы DDS в исходном файле для создания логического файла . Операторы DDS в исходном файле задают имена одного или нескольких физических файлов, служащих основой для логического. Созданный логический файл содержит относительные номера записей данных из одного или нескольких физических файлов.
Оператор SQL " Create view " задает таблицу, представляемую проекцией, вместе с описанием столбцов проекции. Результат создания проекции — логический файл , идентичный создаваемому при использовании "родного" интерфейса.
Логические файлы выполняют три операции: форматирование, включая проекцию, объединение и создание производных полей (field derivation ); выборку записей; упорядочение. Логический файл , созданный с помощью DDS , может осуществлять все три операции. Файл, созданный с помощью SQL, может выполнять либо форматирование (проекция SQL), либо упорядочение (индекс SQL), но не обе сразу. На SQL нельзя создать проекций, выделяющих подмножество записей физического файла. Проекция SQL может быть создана с помощью DDS , но DDS обычно не используется для создания файлов, имеющих только возможности проекций SQL.
Словарь данных и каталоги
Описания компонентов всех физических и логических файлов содержатся на каждой AS/400 в одном месте. В терминах "родного" интерфейса это место называется словарем данных. Словарь данных — это специальный объект OS/400, который обслуживается менеджером базы данных и к которому могут обращаться пользователи для поиска информации о структуре и местах использования файлов. Менеджер базы данных автоматически обновляет информацию в словаре данных всякий раз при создании нового объекта СУБД.
Словарь данных позволяет разработчикам приложений и пользователям получить представление о структуре базы данных на любой системе. "Каковы форматы записей?", "Каковы атрибуты данных?", "Где в системе используется некое имя?", — с помощью словаря данных можно найти ответы на эти и другие вопросы.
В интерфейсе SQL словарь данных называется общесистемным каталогом. SQL также позволяет разработчикам создавать другие каталоги. Каждая коллекция (collection) SQL (библиотека в "нормальной" терминологии) может (хоть и необяза тельно) иметь собственный каталог.
Независимость данных и программ
Использование комбинации физических и логических файлов в AS/400 позволяет достичь независимости программ от используемых ими данных. Отделение описания данных от программ достигается тем, что прикладные программы рассматривают данные в формате, отличном от того в каком они хранятся физически. Концепция отделения программ и данных — одна из основ технологической независимости архитектуры System/38 и AS/400.
Рассмотрим структуру физического файла, содержащего помимо самих данных их описание, часто называемое внешним описанием файла. Как System/38, так и AS/ 400 имеют внешне описанные данные, которые не надо помещать в программу. Это означает, что программа не определяет, как данные должны физически храниться. Кроме того, одна прикладная программа может работать с файлами, содержащими данные в разных форматах.
Формат логического файла , так же как и формат физического — внешний, так что с помощью логических файлов можно переопределить формат записи программы. На рисунке 6.1 показан очень простой пример, иллюстрирующий некоторые функции логических файлов : использование программой логического файла для получения иного представления данных физического файла.
Обратите внимание на выделенные поля. Каждая запись физического файла содержит шесть полей; в то же время программа, посредством логического файла , "видит" только четыре из них. Возможность исключения полей из логического файла позволяет реализовывать защиту на уровне полей. Пользователи имеют доступ только к тем полям, которые им позволено видеть. Это лишь один прием защиты в AS/400 Более подробно тема защиты рассматривается в "Защита от несанкционированного доступа" .
Другая функция, отображенная на рисунке — возможность переупорядочения полей записи. Порядок следования в логической записи полей общего дохода (gross) и федерального подоходного налога (FIT) изменен на обратный. Другими словами, программа независима от порядка следования полей.
Кроме того, рисунок 6.1 иллюстрирует переопределение полей записи. В физическом файле поле общего дохода представляет собой упакованное десятичное число, содержащее 7 цифр, две из которых расположены справа от запятой. Однако программа написана так, что поле общего дохода должно иметь зонный десятичный формат с 8 цифрами, две из которых расположены справа от запятой. Логический файл обеспечивает нужное программе представление, а также осуществляет преобразование между упакованным и зонным десятичным форматами.
Использование множественных логических файлов , построенных над одним и темже физическим файлом, предоставляет альтернативные пути доступа к данным и обеспечивает разделение данных между программами. На рисунке 6.2 показан еще один логический файл для другой программы, который был добавлен к первому примеру. Теперь каждая программа имеет свое представление записей, хранящихся в физическом файле, и доступ только к тем полям, к которым он разрешен. Поля, присутствующие в обоих логических файлах, позволяют программам совместно использовать данные.
Очень важно подчеркнуть, что обе программы работают с теми же самыми физическими данными, — копирования данных нет. Обновление данных, выполненное одной программой, становится немедленно "видимо" другой. Эта возможность работы программ с текущими значениями данных, а не с копиями, используется в System/38 и AS/400 на протяжении уже почти 20 лет.
Для хранения информации, полученной в результате работы программ, используют различные внешние запоминающиеся устройства: гибкие магнитные диски, оптические диски, винчестера и другие носители. Использование внешних запоминающих устройств для хранения информации является наиболее надежным и удобным способом хранения информации.
Организация хранения информации зависит от конкретного носителя, и подробно рассматриваться нами не будет. В общем случае хранение информации организовано в виде именованных областей внешней памяти, называемых файлами. Файл в таком понимании называют физическим файлом.
Файловый тип можно задать одним из трех способов:
Здесь <имя> - имя файлового типа (правильный идентификатор);
File, of - зарезервированные слова (файл, из); TextFile - имя стандартного типа текстовых файлов; <тип> - любой тип Object Pascal, кроме файлов. Например :
Fl = File of Char;
В зависимости от способа объявления можно выделить три вида файлов:
v типизированные файлы (задаются предложением File of . );
v текстовые файлы (определяются типом TextFile);
v нетипизированные файлы (определяются типом File).
В наших примерах F1 - типизированный файл, F2 - текстовый файл, F3 - нетипизированный файл. Вид файла, вообще говоря, определяет способ хранения в нем информации. Однако в Delphi нет средств контроля вида ранее созданных файлов. При объявлении уже существующих файлов программист должен сам следить за соответствием вида объявления характеру хранящихся в файле данных.
Объявить файловую переменную можно используя объявленный в разделе объявления типов файловый тип, например:
В таком случае вы можете применять эту переменную как параметр процедур или функций. Можно также объявить файловую переменную непосредственно в разделе объявления переменных, но тогда подпрограммы для нее недоступны
Var as: file of byte;
Работа с файлами
Для простоты и наглядности файловую переменную можно изобразить как последовательность однотипных компонент хранящуюся на магнитной ленте. В самом начале записывается имя файла, после него компоненты файла, а в самом конце признак конца файла. Считывание или запись информации из файла осуществляется с помощью воображаемой магнитной головки, которую мы в дальнейшем будем называть текущим указателем.
Файл может находиться в различных состояниях:
2. Файл открыт для чтения.
3. Файл открыт для записи.
Установка и завершающие операции
Файлы становятся доступны программе только после выполнения особой процедуры открытия файла. Эта процедура заключается в связывании ранее объявленной файловой переменной с именем существующего или вновь создаваемого файла, а также в указании направления обмена информацией: чтение из файла или запись в него.
Файловая переменная связывается с именем файла в результате обращения к стандартной процедуре AssignFile :
AssignFile (< ф . п .>, < имя файла >);
Здесь <ф.п.> - файловая переменная (правильный идентификатор, объявленный в программе как переменная файлового типа);
<имя файла > - текстовое выражение, содержащее имя файла и, если это необходимо, маршрут доступа к нему.
Инициировать файл означает указать для этого файла направление передачи данных. В Delphi можно открыть файл для чтения, для записи информации, а также для чтения и записи одновременно.
Для чтения файл инициируется с помощью стандартной процедуры Reset;
Здесь <ф. п. > - файловая переменная, связанная ранее процедурой AssignFile с уже существующим файлом.
При выполнении этой процедуры дисковый файл подготавливается к чтению информации. В результате специальная переменная-указатель, связанная с этим файлом, будет указывать на начало файла, т. е. на компонент с порядковым номером 0.
Если делается попытка инициировать чтение из несуществующего файла, возбуждается исключительная ситуация.
Чтобы проверить, существует ли дисковый файл, можно использовать стандартную функцию FileExists, которая возвращает Truе, если указанный при обращении этой функции файл существует, и False - если не существует.
if FileExists(FileName) then
else . // Файл не существует
В Delphi разрешается обращаться к типизированным файлам, открытым процедурой Reset (т. е. для чтения информации), с помощью процедуры write (т. е. для записи информации). Такая возможность позволяет легко обновлять ранее созданные типизированные файлы и при необходимости расширять их. Для текстовых файлов, открытых процедурой Reset, нельзя использовать процедуру Write ИЛИ WriteLn.
инициирует запись в ранее существовавший текстовый файл для его расширения, при этом указатель файла устанавливается в его конец. Процедура Append применима только к текстовым файлам, т. е. их файловая переменная должна иметь тип TextFile (см. выше). Процедурой Append нельзя инициировать запись в типизированный или нетипизированный файл. Если текстовый файл ранее уже был открыт с помощью Reset или Rewrite, использование процедуры Арpend приведет к закрытию этого файла и открытию его вновь, но уже для добавления записей.
Процедуры и функции для работы с файлами
Procedure AssignFile(var F; FileName:String);
Связывает файловую переменную f с именем файла FileName
function ChangeFileExt (const FileName, Extension: String):Strings;
Изменяет существующее расширение файла на расширение, заданное параметром Extension;
Изменяет текущий каталог: path - строковое выражение, содержащее путь к устанавливаемому по умолчанию каталогу;
Procedure CloseFile (var F);
Закрывает файл, однако связь файловой переменной F с именем файла, установленная ранее процедурой AssignFile, сохраняется. При создании нового или расширении старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге. Функции процедуры CloseFile выполняются автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования процедуры AssignFile
Function DateTimeToFileDate(DateTime:TDateTime): Integer;
Преобразует значение DateTime в системный формат времени создания (обновления) файла;
Function DiskFree(D: Byte): Longint;
Возвращает объем в байтах свободного пространства на указанном диске: D - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск В и т, д.). Функция возвращает значение -1, если указан номер несуществующего диска;
function DeleteFile(const FileName:String):Boolean;
Уничтожает файл с именем (и, возможно, маршрутом доступа) FileName. Возвращает True, если операция прошла успешно;
Function DiskSize(D: Byte): Longing;
Возвращает объем в байтах полного пространства на указанном диске: D - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск В и т. д.). Функция возвращает значение -1, если указан номер несуществующего диска;
Function EOF (var F): Boolean;
Тестирует конец файла и возвращает True, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении - что файл исчерпан;
Procedure Erase(var F);
Уничтожает файл f. Перед выполнением процедуры необходимо закрыть файл;
function FileAge(const FileName: String): Integer;
Для файла FileName возвращает время его последнего обновления (в системном формате) или -1, если такого файла не существует;
function ExcludeTrailingBackslash(const S: String): Strings;
Исключает из строки s замыкающий символ “\” (если этот символ не замыкает строку, возвращает S без изменения);
function ExpandUNCFileName(const FileName: String): String;
Дополняет имя файла текущим сетевым каталогом (и диском);
function ExtractFileDir(const FileName: String): Strings;
Извлекает из полного имени файла маршрут доступа к нему (без последнего символа “\”)
function ExtractFileExt(const FileName: String): Strings;
Извлекает из полного имени файла его расширение (с ведущей точкой)
function ExtractFileName(cons t Fi1eName: String): Strings;
Извлекает из полного имени файла его имя (с расширением)
function ExtractFilePath(const FileName: String): Strings;
Извлекает из полного имени файла маршрут доступа к нему (с последним символом “\”)
function ExtractRelativePath(const BaseName, DestName: String): Strings;
Извлекает из полного имени файла имя маршрута относительно DestName (промежуточные каталоги заменяются символами “..\”)
function ExtractShortPathName(const FileName: String): Strings;
Преобразует имя файла к короткому формату 8.3 для MSDOS и Windows 3-х
function FileDateToDateTime(FileDate: Integer) : TDateTime;
Преобразует системный формат FileDate времени создания файла в формат дата-время;
Function FileExists(const FileName: String): Boolean;
Возвращает True, если файл с именем (и, возможно, маршрутом доступа) FileName существует
function FileGetDate(Handle: Integer): Integers;
По заданному дескриптору файла Handle возвращает время и дату его создания в системном формате. Возвращает 0 в случае успеха или код ошибки
function FileSetDate(Handle: Integer; Age:
Для файла с дескриптором Handle устанавливает новое время и дату его создания Age в системном формате.Возвращает 0 в случае успеха или код ошибки
Function FindFirst(const Path: String; Attr: Integer; var F: TSearchRec): Integer;
Procedure FindClose(var F: TSearchRec);
Освобождает память, выделенную для поиска файлов функциями FindFirst/FindNext
Function FindNext(var F: TSearchRec): Integer;
Возвращает в переменой f имя следующего файла в каталоге. Переменная f должна предварительно инициироваться обращением к функции FindFirst. При успешном поиске возвращает значение 0
Очищает внутренний буфер файла и, таким образом, гарантирует сохранность всех последних изменений файла на диске
Procedure GetDir(D: Byte; var S: Strings)
Возвращает имя текущего каталога (каталога по умолчанию): D - номер устройства (0 - устройство по умолчанию, 1 - диск А, 2- диск В и т. д.); s - переменная типа String, в которой возвращается путь к текущему каталогу на указанном диске
function IncludeTrailingBackslash(const S:String): String;
Возвращает полный маршрут доступа к файлу с ведомым символом “\”
Function lOResult: Integer;
Возвращает условный признак последней операции ввода-вывода
function IsPathDelimiter(const S: String; Index: Integer): Boolean;
Возвращает True, если в строке S символ index есть “\”.
function MatchesMask (const Filename, Mask: String): Boolean;
Возвращает True, если имя FileName соответствует групповому имени Mask
Procedure MkDir(Dir: String);
Создает новый каталог на указанном диске: Dir маршрут поиска каталога. Последним именем в маршруте, т.е. именем вновь создаваемого каталога, не может быть имя уже существующего каталога
procedure ProcessPath(const EditText: String; var Drive: Char; var DirPart: String; var FilePart: String);
Возвращает имя диска, маршрут поиска и имя файла в переменных Drive, DirPart и FilePart соответственно. EditText - полное имя файла ;
Procedure Rename(var F; NewName: String);
Procedure Reset(var F: File [; RecSize: Word>);
Открывает существующий файл. RecSize имеет смысл только для не типизированных файлов и указывает размер блока данных
Procedure Rewrite(varFile [; Recsize: ,Word]) ;
Создает новый файл. Recsize имеет смысл только для не типизированных файлов и указывает размер блока данных
Удаляет каталог Dir. Удаляемый каталог должен быть пустым, т. е. не содержать файлов или имен каталогов нижнего уровня
С каждой файловой переменой в момент открытия файла связывается структура данных, которая в числе прочих содержит поле Handle - системный дескриптор файла. Это поле следует использовать При обращении К функциям FileGetTime и FileSetTime. Эти функции, а также функция FileAge и поле Time записи TsearchRec (см. ниже) оперируют системным форматом времени-даты, который можно перевести в стандартный тип дата-время с помощью функции FileDateToDateTime (функция DateTimeToFileDate Осуществляет обратное преобразование).
Подпрограммы FindFirst, FindNext и FindClose позволяют получить доступ к группе файлов, объединенных общими признаками. Эти признаки при обращении к функции FindFirst указываются маской выбора файлов и их атрибутами.
При формировании маски выбора файлов могут использоваться следующие символы-заменители:
* означает, что на месте этого символа может стоять сколько угодно (в том числе ноль) разрешенных символов имени или расширения файла;
? означает, что на месте этого символа может стоять один из разрешенных символов.
* . * выбирает все файлы из каталога;
с* . * выбирает все файлы с именами, начинающимися на с
fcl.pas, ccl2345, с.dat И Т.Д.);
а? . dat выбирает имена файлов типа ао. dat, az. dat и т. д.
Маске выбора может предшествовать маршрут поиска файлов. Например, команда
Параметр Attr при обращении к FindFirst содержит двоичные разряды (биты), уточняющие, к каким именно файлам разрешен доступ. Вот как объявляются файловые атрибуты в модуле SysUtils:
faReadOnly = $01; // Только чтение
faHidden = $02; // Скрытый файл
faSysFile = $04; // Системный файл
faVolumeID = $08; // Идентификатор тома
faDirectory = $10; // Имя подкаталога
faArchive = $20; // Архивный файл
faAnyFile = $3F; // Любой файл
Комбинацией бит в этом байте можно указывать самые разные варианты, например $06 - выбирать все скрытые и/или системные файлы.
Задача. Организовать файл целых чисел из 10 компонент. Определить и вывести на экран среднее арифметическое компонент файла. Вывести содержимое файла на экран.
Type ff = file of Integer ; //Декларация физического файла
Var log _ f : ff ; //Декларация логического файла
Procedure TForm1.FormCreate(Sender: TObject);
Procedure zapolnenie (Var f:ff); //Заполнение файла
Var i:Integer; //Параметр цикла
komp:Integer; //Компонента файла
Rewrite ( f ); //Открытие файла для записи
komp:=StrToInt(Form1.StringGrid1.Cells[i,0]); //ввод компонент
Write ( f , komp ); //запись в файл
Procedure vyvod(Var f:ff); //вывод файла
Reset ( f ); //открытие файла для чтения
While not Eof ( f ) do //пока не конец файла делать
Read ( f , komp ); //чтение следующей компоненты файла
Form1.StringGrid2.Cells[i,0]:=IntToStr(komp); //и вывод ее на экран
CloseFile(f); //закрытие файла
Function sr_ar(Var f:ff):Real; //определение среднего арифметического
Var komp:Integer; //компонента файла
sum:Real; //сумма компонент
Reset ( f ); //открытие файла для чтения
While not Eof ( f ) do //пока не конец файла делать
Read ( f , komp ); //чтение следующей компоненты файла
sum := sum + komp ; //увеличение счетчика суммы
sr _ ar := sum / FileSize ( f ); //получение результата
Procedure TForm1.BitBtn1Click(Sender: TObject);
AssignFile(log_f,'data.dat'); //файл log_f в папке программы имеет имя data.dat
zapolnenie(log_f); //ввести первую строку в StringGridе
Label1.Caption:='Среднее арифметическое компонент файла= '+FloatToStr(sr_ar(log_f));
Читайте также: