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...为什么?
我在这里看到两个问题:
- 您不在上次写入和第一次读取之间
seek
-ing,因此您是在上次写入的位置结束后开始读取。 (你没有立即得到EOFException
的事实表明你的文件在这个程序开始时不是空的运行。)
seek
采用表示字节位置的参数,但 writeInt
和 readInt
写入和读取 四个 字节。因此,如果您不希望整数相互重叠,则需要查找位置 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" 并向前移动适当的字节数。在这里省略 seek
s。
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
使用 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...为什么?
我在这里看到两个问题:
- 您不在上次写入和第一次读取之间
seek
-ing,因此您是在上次写入的位置结束后开始读取。 (你没有立即得到EOFException
的事实表明你的文件在这个程序开始时不是空的运行。) seek
采用表示字节位置的参数,但writeInt
和readInt
写入和读取 四个 字节。因此,如果您不希望整数相互重叠,则需要查找位置 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" 并向前移动适当的字节数。在这里省略 seek
s。
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