我制作了一个简单的数据文件,其中只包含4个字节的标头。这4个字节定义了文件中存储的记录数。标题和记录都是预定义的大小,不能改变。
编辑:此记录也只包含4个字节。它只定义一个整数。 LINE_SEPERATOR = byte {'\ r','\ n'}
我的问题是,每次添加新记录(追加)时,我都需要覆盖标题(不附加),因为记录计数应该增加1。但是程序拒绝在它们之间切换,它只是坚持非追加模式。
addRecord代码:
public void addRecord(ISaveable record)
throws IllegalArgumentException, FileNotFoundException, IOException
{
if(record == null)
{
throw new IllegalArgumentException("The given record may not be null");
}
this.header.increaseRecordCount();
writeHeader();
FileOutputStream oStream = null;
try
{
oStream = new FileOutputStream(DEFAULT_DIR, true);
long offset = calculateOffset(this.header.getRecordCount() - 1, record.getSize());
System.out.println("writing record @ " + offset);
oStream.getChannel().position(offset);
PacketOutputStream pOut = new PacketOutputStream();
record.Save(pOut);
pOut.writeBytes(END_LINE);
oStream.write(pOut.Seal());
}
catch(FileNotFoundException ex)
{
throw ex;
}
catch(IOException ex)
{
throw ex;
}
finally
{
if(oStream != null)
{
oStream.flush();
oStream.close();
}
}
}
writeHeader代码:
private void writeHeader()
throws IOException
{
FileOutputStream oStream = null;
try
{
oStream = new FileOutputStream(DEFAULT_DIR, false);
oStream.getChannel().position(0);
PacketOutputStream pOut = new PacketOutputStream();
this.header.Save(pOut);
pOut.writeBytes(END_LINE);
oStream.write(pOut.Seal());
}
catch(IOException ex)
{
throw ex;
}
finally
{
if(oStream != null)
{
oStream.flush();
oStream.close();
}
}
}
正如您所看到的,我正在使用FileOutputStream的构造函数中的布尔值。给writeHeader一个false(因为我想覆盖现有的头)并且记录为true(因为它应该被添加到文件的末尾)。请忽略设置追加为true的事实,它会自动寻找到底。 calculateOffset方法用于将来的实现。
我做过实验,我每次都只写头。当设置为不附加时,它完美地工作。正如预期的那样,当它被设置为追加时,它将添加多个标题。
我在尝试添加4条记录后立即从我的文件中获得的结果只有2行。标题是完美的,它没有任何问题。但是,所有4条记录都写在下一行上,相互覆盖。
生成的调试文本:
所有记录位置都是正确的,但'3457'是在同一行上覆盖所有4条记录的结果。
答案 0 :(得分:1)
如果您想要写入文件中的多个点,您应该考虑使用专为此目的而设计的RandomAccessFile
。
更新:您还应该为所有写入使用相同的RandomAccessFile
实例,而不是每次更新标题或内容时单独创建一个。