ROBOWEB : Документация : Документация по JAVA , описание JAVA , примеры JAVA , программирование на JAVA , JAVA аплеты , исходники , исходные тексты , source , make программ на JAVA , библиотека классов JAVA , Java WorkShop , Java Studio , компоненты JAVA , свойства события методы JAVA , сокет , передача данных , потоковые сокеты , доступ к файлам , датаграммные сокеты , растровое изображение , видео , звуковые файлы , sun взлом защита скачать бесплатно новые свежие архив секреты недокументированные способы русский перевод компьютер zip каталог add url forum форум чат chat программист программер хакер xakep hack баги компилить сорцы научиться урок обучение домашняя страница home page разработка создание применение примеры способы портал документ знания
Для иллюстрации способов работы с классом RandomAccessFile мы подготовили приложение DirectFile, в котором создается небольшая база данных. Эта база данных состоит из двух файлов: файла данных и файла индекса.
В файле данных хранятся записи, сосотящие из двух полей - текстового и числового. Текстовое поле с названием name хранит строки, закрытые смиволами конца строки "\r\n", а числовое с названием account - значения типа int.
В меню File нашего приложения есть строки New и View records.
С помощью строки New вы можете создать базу данных, состоящую из трех записей. Если выбрать из меню File строку View records, на экране появится диалоговая панель с содержимым этих записей.
Вместо символа перевода строки в диалоговой панели отображается маленький квадратик.
Из этого дампа видно, что после первого запуска приложения в файле данных имеются следующие записи:
Номер записи
Смещение в файле данных
Поле name
Поле account
0
0
Ivanov
1000
1
12
Petrov
2000
2
24
Sidoroff
3000
При последующих запусках каждый раз в файл данных будут добавляться приведенные выше записи.
Так как поле name имеет переменную длину, для обеспечения возможности прямого доступа к записи по ее номеру необходимо где-то хранить смещения всех записей. Мы это делаем в файле индексов.
Файл индексов хранит 8-байтовые смещения записей файла данных в формате long. Зная номер записи, можнор легко вычислить смещение в файле индексов, по которому хранится смещение нужной записи в файле данных. Если извлечь это смещение, то можно выполнить позиционирование в файле данных с целью чтения нужной записи, что и делает наше приложение.
Исходный текст приложения DirectFile
Исходный текст приложения DirectFile представлен в листинге 2.
Для работы с базой данных мы создали класс SimpleDBMS, определив в нем конструктор, методы для добавления записей, извлечения записей по их порядковому номеру, а также метод для закрытия базы данных.
Создание базы данных
Когда пользователь выбирает из меню File строку New, соответствующий обработчик события создает базу данных, передавая конструктору имена файла индекса dbtest.idx и файла данных dbtest.dat:
SimpleDBMS db = new SimpleDBMS(
"dbtest.idx", "dbtest.dat");
После этого с помощью метода AddRecord, определенного в классе SimpleDBMS, в базу добавляются три записи, состоящие из текстового и числового полей:
В этом классе определено три поля с именами idx, dat и idxFilePointer, а также три метода.
Поля класса SimpleDBMS
Поля idx и dat являются объектами класса RandomAccessFile и представляют собой, соответственно, ссылки на файл индекса и файл данных. Поле idxFilePointer типа long используется как рабочее и хранит текущее смещение в файле.
Конструктор класса SimpleDBMS
Конструктор класса SimpleDBMS выглядит достаточно просто. Все, что он делает, - это создает два объекта класса RandomAccessFile, соответственно, для индекса и данных:
idx = new RandomAccessFile(IndexFile, "rw");
dat = new RandomAccessFile(DataFile, "rw");
Так как в качестве второго параметра конструктору класа RandomAccessFile передается строка "rw", файлы открываются и для чтения, и для записи.
Метод close
Метод close закрывает файлы индекса и данных, вызывая метод close из класса RandomAccessFile:
idx.close();
dat.close();
Метод AddRecord
Метод AddRecord добавляет новую запись в конец файла данных, а смещение этой записи - в конец файла индекса. Поэтому перед началом своей работы текущая позиция обоих указанных файлов устанавливается на конец файла.
Для установки мы применили метод seek из класса RandomAccessFile, передав ему в качестве параметра значение длины файла в байтах, определенное при помощи метода length из того же класса:
idx.seek(idx.length());
dat.seek(dat.length());
Перед тем как добавлять новую запись в файл данных, метод AddRecord определяет текущую позицию в файле данных (в данном случае это позиция конца файла) и записывает эту позицию в файл индекса:
Далее метод AddRecord выполняет сохранение полей записи в файле данных. Для записи строки вызывается метод writeBytes, а для записи численного значения типа int - метод writeInt:
Обратите внимение, что к строке мы добавляем символы возврата каретки и перевода строки. Это сделано исключительно для того чтобы обозначить конец строки текстового поля.
Метод GetRecordByNumber
Метод GetRecordByNumber позволяет извлечь произвольную запись из файла данных по ее порядковому номеру.
Напомним, что смещения всех записей хранятся в файле индексов и имеют одинаковую длину 8 байт. Пользуясь этим, метод GetRecordByNumber вычисляет смещение в файле индекса простым умножением порядкового номера записи на длину переменной типа long, то есть на 8 байт, а затем выполняет позиционирование:
idx.seek(nRec * 8);
После этого метод GetRecordByNumber извлекает из файла индексов смещение нужной записи в файле данных, вызывая для этого метод readLong, а затем выполняет позиционирование в файле данных:
Поля записи читаются из файла данных в два приема. Вначале читается строка текстового поля, а затем - численное значение, для чего вызываются, соответственно, методы readLine и readInt:
str = dat.readLine();
account = new Integer(dat.readInt());
Полученные значения полей объединяются в текстовой строке и записываются в переменную sRecord: