writeInt(Integer)覆盖零

问题描述 投票:1回答:2

使用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 ...为什么?

java file randomaccessfile
2个回答
1
投票

这里有两个问题 - 每个int写入时不允许4个字节,当你将ints读回内存时,你不会回到文件的开头。

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

pos - 从文件开头以字节为单位测量的偏移位置,用于设置文件指针。

但是在Java中,ints有4个字节,因此每次后续写入都会覆盖之前int的4个字节中的3个字节。每次都将标记显式设置为4个字节:

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

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

// etc.

或者甚至更容易,标记“做正确的事”并向前移动适当的字节数。请在这里省略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

0
投票

我在这里看到两个问题:

  1. 你不是在上次写作和第一次阅读之间进行seek,所以你在上次写作结束后开始阅读。 (事实上​​,您没有立即获得EOFException表示您的文件在此程序运行开始时不为空。)
  2. seek采用表示字节位置的参数,但writeIntreadInt写入并读取四个字节。因此,如果你不希望你的整数相互重叠,你需要寻找位置0,4,8等,而不是0,1,2等等。(尽管如此,你不要如果您的目标是整数相邻,那么实际上需要您当前对seek的调用。)
© www.soinside.com 2019 - 2024. All rights reserved.