Чтение и запись файлов произвольного доступа
Файлы произвольного доступа рассматриваются как последовательность записей постоянной длины, причем каждая запись является независимой от всех других записей файла. Длина записи определяется в операторе Open, а тип данных, указанный пользователем, определяет ее содержимое. Файлы произвольного доступа используются в основном для хранения двоичных представлений чисел, а не текстов. Применение двоичных чисел экономит пространство файла по сравнению с символьным представлением тех же чисел. Кроме того, двоичные числа загружаются в память компьютера значительно быстрее, так как не требуют преобразования перед использованием.
Открытие файла
Открытие файла произвольного доступа подобно открытию файла последовательного доступа оператором Open, с двумя существенными отличиями: аргумент режима всегда равен Random, а в конце оператора находится аргумент Len=длина_записи.
Для открытия файла произвольного доступа используется следующий оператор Open:
Open имя_файла For Random As файловое_число Len=длина_записи
где имя_файла – строка, содержащая имя и путь файла, подлежащего открытию; файловое_число – номер, который вы хотите присвоить файлу; длина_записи – длина записи произвольного доступа в байтах.
Примечание:
Оптимальная длина записи должна быть кратной размеру дискового сектора, либо делить указанный размер нацело. Большинство дисковых накопителей имеют сектора размером 512 или 1024 байтов; следовательно, оптимальная длина записи должна быть степенью 2, например 32, 64, 128, 256 и т.д. Такая длина является целесообразной потому, что компьютер записывает и считывает данные секторами одинаковой длины. Хотя программа может запросить чтение из дискового файла всего одного байта, компьютер на самом деле прочитает в буфер памяти один или более секторов. Когда ваша программа читает данные из дискового файла, то она фактически читает их из буфера. Когда программа прочитывает весь буфер, компьютер читает в этот буфер следующие несколько секторов из файла. Аналогичным образом данные записываются в дисковый файл: сначала они записываются в буфер памяти, а когда он заполняется, то записываются на диск.
Чтобы понять, почему степень 2 является оптимальной длиной записи, предположим, что размер дискового сектора – 512 байтов, а длина записи файла – 260 байтов. При такой длине записи большинство записей этого файла будут расположены в двух секторах, и для чтения из дискового файла такой записи потребуется прочесть два сектора. Например, запись 2 использует байты с 261 по 512 первого сектора и с 1 по 8 – второго. Применение вместо 260-байтных записей 256-байтных обеспечит упаковку в один сектор двух полных записей, что позволит для ввода записи читать всего один сектор.
Так, следующие операторы открывают файл произвольного доступа для чтения или записи:
FileNum1 = FreeFile
Open “myfile.txt” For Random As FileNum1 Len = 256
Этот блок кода открывает файл произвольного доступа MYFILE.TXT с записями длиной 256 байтов. Функция FreeFile выбирает свободный номер файла.
Примечание:
Двоичные файлы подобны файлам произвольного доступа, с тем отличием, что длина записи двоичного файла всегда равна одному байту и величина, записываемая на диск, всегда помещается в смежные байты.
Закрытие файла произвольного доступа
Файл произвольного доступа, так же как и последовательный файл, закрывается оператором Close:
Close # файловое_число
где файловое_число – номер файла, указанный при открытии этого файла.
Применение оператора Type для определения записи
Оператор Type, применяемый для объявления типа, определяемого пользователем, может применяться также для объявления содержимого переменных типа запись, используемых для работ с файлом произвольного доступа. Оператор Type, используемый для объявления переменных типа запись, подобен применяемому для объявления типа, который определяется пользователем, за исключением того, что при объявлении переменных типа запись вы не используете тип Variant и учитываете, что все строковые переменные должны иметь постоянную длину. Максимальная длина записи, определенной оператором Type, должна быть не больше длины записи, объявленной оператором Open. Однако, если вы будете использовать типы меньшей длины, чем объявлено при открытии файла, то при сохранении каждой записи на диске разность между длиной записи и длиной типа будет расходоваться впустую.
В приведенном ниже примере оператор Type определяет запись длиной в 256 байтов для работы с базой данных личных контактов. Каждая строка имеет постоянную длину, что в обычном операторе Type не требуется.
Type DBEntry 'Определяет структуру записи базы данных.
Name As String * 25
Address As String * 25
City As String * 15
State As String * 2
Zip As String * 10
Phone As String * 20
Net As String * 10
NetAddr As String * 25
Referral As String * 25
Notes As String * 97
RecNo As Integer
End Type 'Размер типа 256 байтов.
Чтобы узнать длину типа, определяемого пользователем, необходимо либо сложить длины всех переменных, входящих в указанный тип, либо объявить переменную указанного типа, а затем применить к ней функцию Len().
Вывод данных в запись
В отличие от файлов последовательного доступа для сохранения данных в файлах произвольного доступа операторы Print или Write не применяются. Вместо них применяется оператор Put. Этот оператор имеет три аргумента – файловое число (номер, присвоенный файлу при открытии), номер записи и переменную типа запись:
Put #файловое_число, номер_записи, переменная
Get #файловое_число, номер_записи, переменная
Так, следующий оператор Put сохраняет содержимое переменной theDB(1) в третьей записи файла, открытого с файловым числом 1:
Put #1, 3, theDB(1)
Если вы опустите номер записи в операторе Put, то будет использован номер, следующий за тем, который был использован в последнем из предыдущих операторов Get, Put или Seek.
Ввод данных из записи
Оператор Get имеет такой же синтаксис, как и оператор Put. Он также имеет три аргумента – файловое число, номер записи и переменную типа запись, получающую данные из записи на диске: