Двоичные файлы с прямым доступом к записям
Оценка 4.8

Двоичные файлы с прямым доступом к записям

Оценка 4.8
docx
18.11.2021
Двоичные файлы с прямым доступом к записям
Л2-002161.docx

Двоичные файлы с прямым доступом к записям

Для сохранения данных в файле и выборочного доступа к записям

(на ввод и вывод).

 

Примечание. Для реализации прямого доступа к записям необходимо иметь способ определения адреса записи в файле. Адресом является смещение до первого байта требуемой записи от начала файла. Первый байт файла имеет смещение 0.

Существует два основных способа решения этой задачи.

 

1.  Все записи файла имеют одинаковую (известную) длину.

В этом случае нет смысла использовать какую-либо дополнительную информацию о месторасположении записей.

1)   Для обеспечения одинаковых размеров всех записей необходи-


мо:


 

       чтобы значения строковой переменной во всех записях имели одинаковую длину. Для этого необходимо каждое значение дополнить пробелами до требуемого размера (см. метод PadRight (int);).


       во-вторых, чтобы все символы – русские и английские – коди- ровались одинаковым количеством байтов (например, по 2 байта), необходимо в классе кодировки выбрать Unicode.

 

2)   При определении адреса требуемой записи, необходимо учесть, что размер каждой строки в записи файла вдвое больше числа ее симво- лов (Unicode 2 байта), плюс один байт на каждую строку записи. В этом байте хранится длина строки.

 

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

 

1.1  Поиск требуемых записей, выполняется на диске

 

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

 

int

kurs = 1;

//4 байта

string

fio = "Иванов

"; //15 символов -> 31 б.

 

fs = new FileStream ("testdata", FileMode.Create); dataOut = new BinaryWriter (fs, Encoding.Unicode); dataOut.Write (kurs);

dataOut.Write (fio);

 

kurs = 2;

fio = "Smit           "; dataOut.Write (kurs); dataOut.Write (fio);

 

kurs = 3;

fio = "Григорьева     "; dataOut.Write (kurs); dataOut.Write (fio);

 

dataOut.Close();

 

fs = new FileStream ("testdata", FileMode.Open); dataIn = new BinaryReader(fs, Encoding.Unicode);

fs.Seek(35, SeekOrigin.Begin); //указатель на 2-ю запись

// Длина записи = 4+(15*2)+1 = 35

 

kurs = dataIn.ReadInt32();         // читаем вторую запись

fio = dataIn.ReadString();

1.2  Все операции с файлом выполняются в оперативной памяти Примечание. Если необходимо осуществлять выборочное чтение

большого количества записей из небольшого двоичного файла (Size < 2 Гб), то предпочтительнее будет прочитать весь файл последовательно в оперативную память, в массивы переменных, входящих в состав запи-


сей. Совокупность всех элементов массивов с одинаковым индексом от- носятся к одному объекту.

 

Постоянная длина записей позволяет определить их количество:

 

int n = (int)fs.Length / 35;             // количество записей

 

Прямой файл всегда может быть прочитан последовательно:

 

int[ ]       kursAr             = new int[n] ; string[ ] fioAr   = new string[n];

. . .

for (int i = 0; i < n; i++)

{

kursAr[i] = dataIn.ReadInt32();      // (i+1) - я

fioAr[i]     = dataIn.ReadString();   //                      запись

}

 

2.  Все записи двоичного файла имеют разную длину.

 

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

Вместо того чтобы обеспечивать постоянство длины записей, при их выводе в файл запоминаются адреса записей в дополнительном (ин- дексном) файле.

Если все адреса записывать в файл индексов в двоичном формате как переменную одного из целых типов (byte, ushort, uint или ulong), то та- кой файл будет файлом с прямым доступом. Техника работы с файлом прямого доступа была описана выше.

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

 

Данный подход можно использовать для прямого доступа к сериали- зованным объектам.

 

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

 

Читать двоичный файл в байтовый массив методом ReadAllBytes() или другим байтовым методом, а затем организовывать выборку данных из этого массива, кажется простой задачей. Но отображение байтов на типы данных – это непростые алгоритмы.

 

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

 

Если прямой доступ не требуется, файл может быть любым – и тек- стовым, и двоичным.


Если файл должен просматриваться в текстовом редакторе файл дол- жен быть текстовым.


 

Двоичные файлы с прямым доступом к записям

Двоичные файлы с прямым доступом к записям

Unicode. 1) При определении адреса требуемой записи, необходимо учесть, что размер каждой строки в записи файла вдвое больше числа ее симво- лов (Unicode – 2…

Unicode. 1) При определении адреса требуемой записи, необходимо учесть, что размер каждой строки в записи файла вдвое больше числа ее симво- лов (Unicode – 2…

Совокупность всех элементов массивов с одинаковым индексом от- носятся к одному объекту

Совокупность всех элементов массивов с одинаковым индексом от- носятся к одному объекту

Если файл должен просматриваться в текстовом редакторе файл дол- жен быть текстовым

Если файл должен просматриваться в текстовом редакторе файл дол- жен быть текстовым
Скачать файл