簡體   English   中英

RandomAccessFile正確寫入文件,但是在檢索記錄時失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM