以下是主要代码:
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)。在那之后,我存储了关于index的数据——这是一个linkedhashmap,其中的键与dictionary中使用的键相同,它的值是indexrecord示例,它包含两个整数值:第一个是指向一个字节的指针,关于这个键的数据从该字节开始,第二个是该信息的长度(也以字节为单位)。文件的最后一部分存储有关字典的信息。
所以这个程序的要点是我不想把每个字典元素都加载到内存中。我只想加载索引,每当我需要字典键的描述时,我都会使用索引记录从文件中加载所需的数据。
好吧,那有什么问题?问题是,无论是读还是写字典的第一个元素,总有一些错误。如果运行该程序,您将看到“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
与字典中未注解的“test”示例的结果相比:
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:我知道一些“解决方案”可能是在字典中添加一个元素作为第一个无法读取的元素,但我不想这样做。我想了解代码的错误,以便更好地理解这个类。
暂无答案!
目前还没有任何答案,快来回答吧!