RandomAccessFile записывает в файл правильно, но при поиске записей это не удается
Я студент по информатике, изучаю диплом IB. У меня есть задание, включающее класс RAF(RandomAccessFile), и я должен использовать его в следующей программе. Я понимаю, что лучше использовать ArrayList и сериализацию программы в файл, но это будет на моем экзамене, и в результате я должен изучить это. Это моя третья попытка понять эту концепцию, и она сводит меня с ума.
Цель этой программы - заполнить файл.dat записями одинакового размера с разными полями. В конце концов, программа должна представлять собой графический интерфейс с различными отображаемыми полями, и она должна позволять пользователю добавлять записи, а также искать, сортировать, редактировать и удалять записи.
GUI, который я создал в NetBeans, выглядит следующим образом:
И так как мне нужно создавать записи на основе размера байта каждого поля, я разработал следующее изображение, которое содержит максимальный размер каждого поля в количестве символов, а также пример изображения для проверки моих рассуждений:
Поняв, что размер байта каждой записи равен 102, я использовал эти знания для дальнейшего развития программы, создав метод записи записей в двоичный файл. Затем я создал один, который предназначен для возвращения записей в файл. Тем не менее, здесь все идет не так, как надо. Если я введу только одну запись, это почти нормально. Я могу ввести эту единственную запись...
Но если я закрою программу, а затем снова открою ее, возраст лошади изменится:
и если я попытаюсь получить более одной записи одновременно, программа не получит их все:
Конечно, здесь я просто использовал 'smashes клавиатуры' для быстрого заполнения большего количества записей, но, как вы можете видеть, он объединяет разные записи и помещает их все в один столбец таблицы. Этого не должно случиться.
Наконец, я получаю это исключение каждый раз:
Apr 12, 2016 10:18:17 PM horsemanager.HorseManager <init>
SEVERE: null
java.io.EOFException
at java.io.RandomAccessFile.readChar(RandomAccessFile.java:773)
at horsemanager.BinaryFile.getString(BinaryFile.java:118)
at horsemanager.BinaryFile.readNextRecord(BinaryFile.java:99)
at horsemanager.HorseManager.<init>(HorseManager.java:38)
at horsemanager.HorseManager$7.run(HorseManager.java:453)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Это исключение происходит независимо от количества записей в файле.
BinaryFile.getString ():
public static String getString(int maxLength) throws IOException{
//maxLength indicates the maximum length of the particular field(eg. the horses name is maximum 25 characters so the maxLength in that case would be 25)
String concat = ""; //to pull the entire string from the file
int length = raf.readShort(); //to get the length of the string
for(int j = 0 ; j<length; j++){ //to make sure to get the whole word
concat += raf.readChar();
//gets the word character by character. also, this is the line that has the error
}
for(int i=length; i<maxLength; i++){ //to skip forward if there is any blank space following the String
raf.readChar();
}
return concat; //returns the full string
}
BinaryFile.readNextRecord ():
public static Object[] readNextRecord(int recordNumber) throws IOException {
ID++;
raf.seek(recordNumber * RecordLength);
Object[] horse = {ID,
getString((int)ShowNameLength),
getString((int)BarnNameLength), //this line is the one that garners the error
getString((int)CoatColorLength),
getShort()} ;
return horse;
}
Я чувствую, что мои исключения происходят из-за способа записи записей в файл, но я не уверен, что любые изменения, которые я внес в файл, ничего не изменили.
Если нужна дополнительная информация, спросите меня! В противном случае это полный класс BinaryFile.java: http://pastebin.com/FWzmL2Aa
и это полный класс HorseManager.java: http://pastebin.com/hsHVmQFT
1 ответ
Вы используете это, чтобы написать возраст. Это в основном записывает возраст в виде последовательности 16-битных символов в файл.
public static void writeShort(int maxLength, short a) throws IOException {
int length;
String A = a + ""; // changing short to String
if (A.length() < maxLength) {
length = A.length();
} else {
length = maxLength;
A = A.substring(0, maxLength);
}
int toBlanc = maxLength - length;
char pointer;
// writing the age as a sequence of 16 bit characters.
for (int j = 0; j < A.length(); j++) {
pointer = A.charAt(j);
raf.writeChar(pointer);
}
for (int j = 0; j < (maxLength - A.length()); j++) {
raf.writeChar(' ');
}
}
Вы используете это, чтобы прочитать возраст. Это читает возраст как короткий.
public static short getShort() throws IOException{
return raf.readShort();
}
https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html
Ваш пример: возраст меняется с 12 до 49
Когда вы пишете 12 лет, вы пишете 16 битов символа "1", за которыми следуют 16 битов символа "2". Когда вы читаете возраст, ваш readShort() будет читать только первые 16 битов и считать их двоичным представлением короткого замыкания. Двоичный код для '1' - 0000 0000 0011 0001 readShort() интерпретирует это как 49. Теперь второй набор из 16 битов интерпретируется как что-то еще, и все последующие записи перемешиваются.
Решение
Сделайте ваши readShort и writeShort согласованными.