writeInt(Integer) 覆盖零

writeInt(Integer) overwrites zero

使用 RandomAccessFile class,我正在尝试测试 writing/reading to/from 中文件的概念 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...为什么?

我在这里看到两个问题:

  1. 您不在上次写入和第一次读取之间 seek-ing,因此您是在上次写入的位置结束后开始读取。 (你没有立即得到EOFException的事实表明你的文件在这个程序开始时不是空的运行。)
  2. seek 采用表示字节位置的参数,但 writeIntreadInt 写入和读取 四个 字节。因此,如果您不希望整数相互重叠,则需要查找位置 0、4、8 等,而不是 0、1、2 等(尽管碰巧,您不需要如果您的目标是使整数相邻,则实际上不需要您当前对 seek 的调用。)

这里有 2 个问题 - 您不允许每个 int 写入 4 个字节,并且在将 int 读回内存时您没有返回到文件的开头。

首先,seek 方法将字节数作为文件偏移量的参数。

pos - the offset position, measured in bytes from the beginning of the file, at which to set the file pointer.

但在 Java 中,int 有 4 个字节,因此您将在每次后续写入时覆盖前一个 int 的 4 个字节中的 3 个。要么显式设置标记为每次后4个字节:

storage.seek(4);
storage.writeInt(2);

storage.seek(8);
storage.writeInt(3);

// etc.

或者更简单,标记 "does the right thing" 并向前移动适当的字节数。在这里省略 seeks。

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