logo
Разработка автоматизированной системы "Склад"

3.1 Работа с файлами

При проектировании приложения достаточно часто возникает необходимость работать непосредственно с файлами. Это требуется, например, для добавления, удаления файлов или каталогов (папок), записи данных в файлы или чтения из них как программно, так и в интерактивном режиме. Необходимость работы с файлами возникает также при создании программы инсталляции разработанного приложения на пользовательские компьютеры, чтения данных из файлов при инициализации приложения с использованием файлов настройки, организации вывода файлов на печать. Для этих целей Visual Basic предоставляет полный набор функций, работающих с файлами, папками и устройствами, дающий возможность производить с ними все необходимые действия.

В Visual Basic существует понятие типа файла, который определяется организационной структурой хранения информации в файле и способом доступа к этой информации. Принято выделять следующие типы файлов.

Файлы последовательного доступа. Как правило, это текстовые файлы или аналогичные им. Такие файлы представляют собой последовательность символов. При этом данные могут быть с разделителями или без разделителей, то есть содержание файла может иметь некую структуру. Структурной единицей содержимого в подобных файлах, как правило, является строка. Примерами этих файлов могут служить текстовые файлы и файлы инициализации программ.

Файлы произвольного доступа. Это структурированные файлы, которые содержат информацию в виде записей. Примером могут служить файлы баз данных.

Двоичные (бинарные) файлы. Файлы с побайтным доступом. В принципе, это те же файлы с последовательным доступом, но информация в них не организована в строки. Особенность данных файлов - работа с байтами или блоками байтов. К таким файлам можно отнести выполняемые программы, файлы динамических библиотек, файлы документов Word.

Подобное деление файлов на типы достаточно условно и определяется особенностями организации файлов и доступа к данным в них. Например, файл с последовательным доступом можно открыть и в режиме двоичного доступа. Если этот файл имеет разделители, то для работы с ним придется написать специальную процедуру обработки разделителей и разбора данных, так как двоичный доступ обеспечивает побайтную запись/чтение из файла. Очевидно, что это неудобно. Именно поэтому и введено условное деление файлов на типы в зависимости от формата файла и доступа к данным. Соответственно сгруппированы и функции Visual Basic для записи/чтения данных. Мы рассмотрим работу с каждым из типов файлов, понимая, что такое разделение на типы достаточно условно, но позволяет обеспечить наиболее эффективную обработку данных для каждого типа.

Тип файла задает оптимальный набор функций записи и чтения данных из файла. Поэтому при работе с файлами для написания эффективной программы всегда необходимо иметь представление о типах файлов, с которыми будет работать программа, и об организации хранения данных в этих файлах. Это дает возможность обеспечить оптимальный доступ и использовать соответствующие этому доступу функции.

Традиционный подход при работе с файлами остается неизменным практически с самых первых версий Visual Basic и заключается в использовании функций и операторов, обеспечивающих прямой доступ к информации в файлах. Функции и операторы, используемые при работе с файлами, приведены в табл. 1. В столбце Тип файла этой таблицы приняты следующие сокращения типов файлов:

§ П - файл последовательного доступа;

§ Пр - файл произвольного доступа;

§ Б - бинарный файл.

Мы рассмотрим только основные функции и операторы, необходимые для получения навыков работы с файлами.

Таблица 1. Функции и операторы для работы с файлами

Функция, оператор

Описание

Тип файла

Open

Открывает файл

П, Пр, Б

Close

Закрывает все файлы

П, Пр, Б

Close #

Закрывает файл по идентификатору (дескриптору)

П, Пр, Б

Print tt

Записывает данные в файл

П

EOF

Определяет метку конца файла

П, Пр, Б

Seek

Устанавливает на заданную номером позицию или запись в файле

П, Пр, Б

Kill

Удаляет файл

П, Пр, Б

Name

Задает (переименовывает) имя файла

П, Пр, Б

Get #

Читает данные из файла

Пр.Б

Input

Читает данные из файла

П, Б

Input #

Читает данные из файла

П

Line Input #

Читает строку из файла

П

Put #

Записывает данные в файл

Пр, Б

Write #

Записывает данные в файл

П

Файл с произвольным доступом обладает заранее заданной структурой и состоит из записей. Каждая запись в файле - это некоторая порция данных, которая имеет строго определенный размер и свой конкретный номер в файле. Доступ к данным в файле произвольного доступа осуществляется именно по номеру записи. Данные из файла такого типа читаются и записываются записями. Примерами файла произвольного доступа являются базы данных, всегда имеющие строго определенную структуру.

При открытии файлов произвольного доступа возможен только один режим доступа - Random. Кстати, этот режим является режимом по умолчанию для функции Open.

Используя возможности Visual Basic, можно создать файл произвольного доступа пользовательской, то есть своей собственной структуры. Продемонстрируем это на небольшом примере. С помощью оператора туре объявим тип переменной, имеющей заданную.структуру записи:

Type PhisFace

PhisFaseID As Integer

FIO As String * 50

End Type

В данном примере объявлена структура в виде записи из двух полей. Первым полем является идентификатор, а вторым - фамилия, имя и отчество.

Открытие файла произвольного доступа

Файл произвольного доступа открывается несколько иначе, чем файл последовательного доступа. Синтаксис оператора open при этом выглядит следующим образом:

Open pathName [For Random] As fileNumber Len = recLength

где:

§ pathName - полное имя файла;

§ fileNumber - номер файла;

§ recLength - длина записи в байтах.

При использовании оператора Open для открытия файла произвольного доступа атрибут For не обязателен, так как в Visual Basic этот параметр устанавливается по умолчанию. Как видно из синтаксиса, в отличие от файла с последовательным доступом, при открытии файла с произвольным доступом необходимо обязательно указывать длину записи. При этом, если длина записи не известна, ее можно вычислить с использованием функции Len.

Чтение данных из файла произвольного доступа

Данные из файла произвольного доступа, как правило, считываются записями. Для этого используется оператор Get #, который имеет следующий синтаксис:

Get #fileNumber, [recNumber], varName

где:

§ fileNumber - номер файла;

§ recNumber - номер записи в файле;

§ varName - переменная.

Если параметр recNumber в функции Get не указан, считывается текущая запись, на которой позиционирован указатель.

Для позиционирования указателя можно использовать функцию seek. Синтаксис этого оператора такой же, как для файлов последовательного доступа, но имеет другой смысл. Если для последовательных файлов позиционирование выполняется по символам, то для файлов произвольного доступа - по номеру записи:

Seek #fileNumber, position

где:

§ fileNumber - номер файла;

§ position - целочисленное выражение, которое задает номер записи в файле.

Запись в файл произвольного доступа

Для записи данных в файл произвольного доступа используется оператор Put #, имеющий следующий синтаксис:

Put #fileNumber, [recNumber], varName

где:

§ fileNumber - номер файла, аналогичный номеру в операторе open;

§ recNumber - целочисленное выражение, которое задает номер записи в файле;

§ varName - переменная, указывающая источник записываемых данных.

Этот оператор используется только для файлов произвольного доступа и бинарных. Если номер записи не указан, то по умолчанию принимается текущая позиция указателя записи.

При использовании оператора Put необходимо иметь в виду, что данные в записи с указанным в операторе номером будут заменены на те, которые мы записываем в файл. Добавление записей выполняется при помощи этого же оператора, но с некоторыми особенностями. Об этом речь пойдет в следующем разделе.

Изменение данных в файле произвольного доступа

Для изменения данных в записях файла (редактирование, добавление, удаление записей) применяется оператор put ft. При его использовании необходимо иметь в виду, что данные в записи будут заменены на те, которые мы передаем в файл. Подчеркнем, что новая запись с данными не создается.

Для добавления записей в файл необходимо указывать номер записи на единицу больший номера последней записи. В этом случае запись будет добавлена в файл, а не изменена. Например:

Put #FileNum, LastRecord + 1, ForFileRecords

Для вычисления текущего номера последней записи LastRecord можно использовать длину записи и размер файла, возвращаемый функцией LOF.

Перейдем к описанию процесса удаления данных из файла произвольного доступа. Существуют два способа. Можно просто очистить соответствующие поля указанных записей, то есть записать в них пустые значения. Однако в этом случае в файле остаются пустые записи. Понятно, что при таком подходе ресурсы (дисковое пространство) используются нерационально.

Для окончательного удаления записей рекомендуется перезаписывать данные в новый файл, пропуская пустые записи. Алгоритм этих действий таков:

1. Создайте новый файл с помощью оператора Open.

2. Перепишите все непустые записи в новый файл, используя оператор Put #.

3. Закройте исходный файл и удалите его при помощи оператора Kill.

4. Переименуйте новый файл в исходный оператором Name.

Получаем тот же самый файл, но уже без пустых записей. При этом экономится пространство диска и время поиска данных в таком файле.