Search code examples
javarandomaccessfile

java.io.EOFException Thrown everytime I read a RandomAccessFile


So I'm creating a Database for games for a school project using Random Access File. I'm pretty sure I got the basics down and I re-read the code a million times, I just cant seem to find what's wrong with reading the Random Access File bytes properly.. I calculated the values for each word multiple times to double check too...

My main method:

public static void main(String[] args) {
    RAFProcessing raf = new RAFProcessing();
    try {
        RandomAccessFile file = new RandomAccessFile(new File(
                "src/FirstTry/database.txt"), "rw");

        raf.writeRecord("Fifa", "EA", 2001, file);

        raf.readRecord(file);

        file.close();
    }

    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Writing Data + Bytes inbetween:

public void writeRecord(String gameName, String publisher, int year, RandomAccessFile file) throws IOException
{
    Long fileSize = file.length();
    file.seek(fileSize);

    file.writeUTF(gameName);
    for(int loop=0; loop<20-gameName.length(); loop++ )
    {
        file.writeByte(20);
    }

    file.writeUTF(publisher);
    for(int loop=0; loop<20-publisher.length(); loop++ )
    {
        file.writeByte(20);
    }

    file.writeInt(year);
}

Vale of SIZE is 48 (22 + 22 + 4)

Reading Data and Bytes:

public void readRecord(RandomAccessFile file) throws IOException
{
    file.seek(0);
    String wholeRecord ="";
    int totalRecord = (int) (file.length()/SIZE);
    System.out.print(totalRecord);
    String gameName, publisher;
    int year;


    for(int loop=0; loop< totalRecord; loop++)
    {
        gameName = file.readUTF();
        for(int innerloop=0; innerloop<20-gameName.length(); loop++ )
        {
            file.readByte();
        }

        publisher = file.readUTF();
        for(int innerloop=0; innerloop<20-publisher.length(); loop++ )
        {
            file.readByte();
        }

        year = file.readInt();

        wholeRecord += "|Game Name:" + gameName + " | Publisher: " + publisher + " | Year Published: " + year + "\n";
    }

    System.out.println( wholeRecord);
}

Solution

  • for (int innerloop = 0; innerloop < 20 - gameName.length(); loop++)
    

    The problem is here. It should be:

    for (int innerloop = 0; innerloop < 20 - gameName.length(); innerloop++)
    

    (twice).

    However:

    1. SIZE is an invalid assumption. You can't assume that the writeUTF() representation of a string uses the same number of bytes as there are characters in the string, plus 2 for the length word.
    2. It would be simpler from the coding point of view to just pad the string with spaces before writing them, and trim them after reading. But you still can't assume that each record will be the same size.
    3. A file containing writeUTF() and writeInt() data is not text and should not have the .txt extension.