[英]RandomAccessFile writing to file properly, but upon retrieval of records it fails
我是一名計算機科學專業的學生,正在學習IB文憑。 我有一個涉及RAF(RandomAccessFile)類的作業,我必須在以下程序中使用它。 我知道使用ArrayList並將程序序列化到文件會更好,但這是我的考試,因此,我必須學習這一點。 這是我第三次嘗試理解這個概念,這使我發瘋。
對於我來說,這個程序的目標是讓一個.dat文件充滿記錄 -每個記錄大小相同,並且其中包含不同的字段。 最后,該程序應該是一個顯示不同字段的GUI,它應該允許用戶添加條目以及搜索,排序,編輯和刪除條目。
我在NetBeans中創建的GUI如下所示:
由於我需要根據每個字段的字節大小創建記錄,因此設計了以下圖像,其中包含每個字段的最大字符數(以字符數為單位)以及示例圖像以驗證我的推理:
在意識到每個記錄的字節大小為102之后,我通過創建一種將記錄寫入binaryFile的方法來利用該知識來進一步擴展程序。 然后,我創建了一個旨在將記錄帶回到文件中的記錄。 但是,這就是問題所在。 如果我只輸入一條記錄,那幾乎可以。 我可以輸入這條記錄...
但是,如果我關閉程序然后重新打開它,則馬的年齡會改變:
如果我嘗試一次檢索多個條目,該程序將不會檢索所有這些條目:
當然,在這里,我只是使用“鍵盤粉碎”來快速填寫更多記錄,但是如您所見,它結合了不同的記錄並將它們全部放入表的該列中。 那不是要發生的。
最后,我每次都會收到此異常:
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
您正在使用它來寫年齡。 這基本上是將年齡作為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#readShort%28%29
您的示例:年齡從12歲更改為49歲
當您寫12歲時,您正在寫16位字符“ 1”,然后是16位字符“ 2”。 當您讀取年齡時,您的readShort()將僅讀取前16位,並假定它們是short的二進制表示形式。 “ 1”的二進制是0000 0000 0011 0001 readShort()將此解釋為49。現在第二組16位被解釋為其他內容,並且所有后續記錄都被弄亂了。
解
使您的readShort和writeShort保持一致。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.