#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 — хороший выбор.