Атрибуты объекта к представлению одинаковой длины для более быстрого чтения

#java

#java

Вопрос:

Я хочу преобразовать атрибуты моего объекта ‘person’ в представление, в котором я могу записывать строки в файл, представляющий каждого пользователя. Нескольким машинам необходимо одновременно считывать выделенный им фрагмент файла, и поэтому вместо этого я перехожу от строк текста, закодированного в символах, к списку байтов. Я надеюсь, что из-за того, что представление каждого пользователя имеет одинаковую длину, мне не нужно читать каждый символ, и приложение для чтения может «перейти» туда, где ему нужно начать чтение.

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

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

 byte[] person = new byte[8];
person[0] = Integer.byteValue(age);
if (gender.equals('m')) {person[1] = Integer.byteValue(1);}
else {person[1] = Integer.byteValue(0);}
person[2] = Integer.byteValue(children);
person[3] = Integer.byteValue(goodHealth? 1:0);
person[4] = Integer.byteValue(cars);
person[5] = Integer.byteValue(avgWeekShopping);
person[6] = Integer.byteValue(salary);
person[7] = Integer.byteValue(smoker? 1:0);
  

Надеюсь, можно понять, чего я пытаюсь достичь. Приветствия.

Комментарии:

1. Есть ли какая-либо причина, по которой все они должны находиться в одном файле? Или, если уж на то пошло, почему бы просто не поместить это в базу данных?

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

3. учитывая, что данные еще не записаны (потому что вы выясняете, как это сделать в этом сообщении), почему вы не могли бы использовать базу данных? В нем уже решены эти проблемы. Любая приличная база данных (mysql, черт возьми, даже derby) может справиться с этой проблемой.

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

Ответ №1:

Развивая ответ @trashgod, вашу проблему можно разделить на две части; кодирование данных и обеспечение того, чтобы закодированные данные могли быть представлены в записях одинаковой длины.

Очевидный способ кодирования данных заключается в следующем:

 byte[] bytes;
try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream(/* size hint */);
    DataOutputStream dos = new DataOutputStream(baos);
    dos.writeInt(age);
    dos.writeBoolean(gender.equals('m'));
    dos.writeInt(children);
    dos.writeBoolean(goodHealth);
    dos.writeInt(cars);
    dos.writeInt(avgWeekShopping);
    dos.writeInt(salary);
    dos.writeBoolean(smoker);
    bytes = baos.toByteArray();
} catch (IOException ex) {
    throw new AssertionError("this can't happen", ex);
}
  

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

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


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

Комментарии:

1. Спасибо за ваш ответ. Количество полей всегда будет таким, как указано выше. Компилятору не нравится метод getBytes. Есть идеи, почему? Спасибо

2. toByteArray() ?

3. похоже, это правильный метод. мне пришлось перехватить исключение ввода-вывода, но все равно не будет компилироваться, поскольку не удается найти символ ‘bytes’ при попытке его вернуть.

4. @bashcrufter: Объявить bytes вне try…catch блока.

Ответ №2:

Вместо этого вы можете захотеть взглянуть на DataOutputStream и DataInputStream .

Как предполагает @glowcoder, база данных может выполнять арбитраж между одновременными пользователями, и она более масштабируема. База данных H2 — хороший выбор.