RandomAccessFile 类 - 读取/写入 LinkedHashMap

主要代码如下:

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {

        RandomaccessFile raf = new RandomaccessFile("test.dat","rwd");
        Map<String,String> dictionary = new LinkedHashMap<>();
        Map<String,IndexRecord> mapthatWritesToFile = new LinkedHashMap<>();
        Map<String,IndexRecord> mapthatReadsFromFile = new LinkedHashMap<>();
//        dictionary.put("Test","test");
        dictionary.put("Java","Best programming language");
        dictionary.put("T-SQL","Database language");
        dictionary.put("None","Doesn't matter");

        int pointerToDictionaryData = Integer.BYTES; // I add 4 bytes,because this number is going to be the first data written to file.
        int tempPointer = pointerToDictionaryData;
        for(String part : dictionary.keySet()){
            pointerToDictionaryData += part.getBytes().length + (2*Integer.BYTES); // adding bytes from String + 2x Integer.Bytes for startByte and length of data.
        }
        raf.writeInt(pointerToDictionaryData);

        int pointerToIndex = (int) raf.getFilePointer();
        raf.seek(pointerToDictionaryData);
        for(String key : dictionary.keySet()){
            StringBuilder sb = new StringBuilder(key);
            sb.append("=");
            sb.append(dictionary.get(key));
            raf.writeUTF(sb.toString());

            IndexRecord record = new IndexRecord(tempPointer,(int) (raf.getFilePointer() - tempPointer));
            mapthatWritesToFile.put(key,record);
            tempPointer = (int) raf.getFilePointer();
        }

        raf.seek(pointerToIndex);
        for(String key : mapthatWritesToFile.keySet()){
           raf.writeUTF(key);
           raf.writeInt(mapthatWritesToFile.get(key).getStart());
           raf.writeInt(mapthatWritesToFile.get(key).getLength());
        }

        raf.seek(0);
        pointerToDictionaryData = raf.readInt();

        while(raf.getFilePointer() < pointerToDictionaryData){
            String key = raf.readUTF();
            int start = raf.readInt();
            int length = raf.readInt();
            mapthatReadsFromFile.put(key,new IndexRecord(start,length));
        }

        for(String key : mapthatReadsFromFile.keySet()){
            System.out.println("Reading: " + key);
            System.out.println(key + " | starts at byte: " + mapthatReadsFromFile.get(key).getStart() +
                    " and is " + mapthatReadsFromFile.get(key).getLength() + " bytes long");
            raf.seek(mapthatReadsFromFile.get(key).getStart());
            System.out.println("Result: " + raf.readUTF() + "\n");
        }
    }
}

这里还有必要的 IndexRecord 类:

public class IndexRecord {

    private int start;
    private int length;

    public IndexRecord(int start,int length) {
        this.start = start;
        this.length = length;
    }

    public int getStart() {
        return start;
    }

    public int getLength() {
        return length;
    }
}

那么到底是什么问题呢?也许我将从这个程序的目的开始。我正在尝试学习如何使用 RandomaccessFile 类,并创建了一个将三个部分写入文件的代码。

第一个是指向存储字典元素的文件部分的指针(格式为key=description)。之后,我存储有关索引的数据 - 这是一个 LinkedHashMap,其键与字典中使用的键相同,其值是 IndexRecord 实例,其中包含两个 Integer 值:第一个包含指向有关此键的数据的字节的指针,以及第二个是该信息的长度(以字节为单位)。文件的最后一部分是存储字典信息。

所以这个程序的重点是我不想将每个字典元素都加载到内存中。我只想加载索引,每当我需要字典键的描述时,我都会使用适当的索引记录从文件中加载所需的数据。

好的 - 那么问题是什么?问题是,读取或写入字典的第一个元素总是有问题。如果您将运行该程序,您将看到“Java”的值长度错误,并且它也不会读取该键的值。如果您取消对字典的“Test,Test”输入的注释,您将看到 Java 的值现在可以正确读取并且长度正常,但是“Test”键的数据再次被窃听。

字典中带有注释“Test”实例的结果:

Reading: Java
Java | starts at byte: 4 and is 69 bytes long
Result: Java

Reading: T-SQL
T-SQL | starts at byte: 73 and is 25 bytes long
Result: T-SQL=Database language

Reading: None
None | starts at byte: 98 and is 21 bytes long
Result: None=Doesn't matter

对比字典中未注释“测试”实例的结果:

Reading: Test
Test | starts at byte: 4 and is 60 bytes long
Result: Test

Reading: Java
Java | starts at byte: 64 and is 32 bytes long
Result: Java=Best programming language

Reading: T-SQL
T-SQL | starts at byte: 96 and is 25 bytes long
Result: T-SQL=Database language

Reading: None
None | starts at byte: 121 and is 21 bytes long
Result: None=Doesn't matter

如您所见 - 字典的第一个元素的长度总是有问题,并且没有正确读取(或者之前没有正确写入)。

如果问题太大,我很抱歉,但我想包括所有重要的信息,以便您可以很好地了解程序是什么,它做什么以及有什么问题。

PS:我知道一些“解决方案”可能是将一个元素添加到字典中作为第一个无法读取的元素,但我不想这样做。我想了解代码有什么问题,以便更好地理解课程。

xjdyjk2007 回答:RandomAccessFile 类 - 读取/写入 LinkedHashMap

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/30326.html

大家都在问