我使用RandomAccessFile
类,尝试测试在Java中向文件写入/从文件读取的概念。所以我尝试了这段代码:
public static void main (String[] args) throws IOException {
RandomAccessFile storage = new RandomAccessFile("FILE.txt", "rw");
storage.seek(0);
storage.writeInt(1);
storage.seek(1);
storage.writeInt(2);
storage.seek(2);
storage.writeInt(3);
storage.seek(3);
storage.writeInt(4);
storage.seek(4);
storage.writeInt(5);
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
storage.close();
我认为它应该打印: 1个 2 3 4 5
但是会发生以下情况: 3 4 5 EOFException ...为什么?
答案 0 :(得分:1)
这里有2个问题-您不允许每个int
写入4个字节,并且在将int
读回内存时也没有寻找文件的开头。
首先,seek
方法将字节数的参数作为文件的偏移量。
pos
-从文件开头算起的偏移位置,以字节为单位设置文件指针。
但是在Java中,int
有4个字节,因此每次后续写入操作都将覆盖前int
的4个字节中的3个。每次以后都将标记显式设置为4个字节:
storage.seek(4);
storage.writeInt(2);
storage.seek(8);
storage.writeInt(3);
// etc.
甚至更容易地,标记“做正确的事”并向前移动适当数量的字节。只需在此处忽略seek
。
storage.writeInt(1);
storage.writeInt(2);
storage.writeInt(3);
storage.writeInt(4);
storage.writeInt(5);
第二个问题是,当回读字节时,您不会将标记重设回文件的开头,从而导致EOFException
。添加对seek(0)
的调用,以将标记发送回文件的开头。
storage.seek(0);
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
System.out.println(storage.readInt());
然后我得到输出:
1
2
3
4
5
答案 1 :(得分:0)
我在这里看到两个问题:
seek
的情况,因此您要在上次写入的位置结束之后开始读取。 (事实上,您没有立即得到EOFException
,这表明在此程序运行开始时文件不为空。)seek
接受表示字节位置的参数,但是writeInt
和readInt
写入和读取四个字节。因此,如果您不希望整数相互重叠,则需要查找0、4、8等位置,而不是0、1、2等位置。(尽管发生了这种情况,如果您的目标是使整数相邻,则实际上需要您当前对seek
的调用。)