gpt4 book ai didi

java - FileOutputStream 在追加和覆盖之间切换

转载 作者:行者123 更新时间:2023-12-01 12:28:16 28 4
gpt4 key购买 nike

我制作了一个简单的数据文件,其中包含仅 4 个字节的 header 。这 4 个字节定义了文件内存储的记录数。 header 和记录都是预定义的大小,不能改变。

编辑:该记录也仅包含 4 个字节。它只定义一个整数。LINE_SEPERATOR = 字节 { '\r', '\n' }

我的问题是,每次添加新记录(追加)时,我都需要覆盖标题(而不是追加),因为记录数应该增加一。然而,程序拒绝在它们之间切换,它只是坚持非追加模式。

添加记录代码:

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 的构造函数中正确使用了 boolean 值。将 writeHeader 设置为 false(因为我想覆盖现有 header )并将记录设置为 true(因为应该将其添加到文件末尾)。请忽略设置append为true它会自动查找到末尾的事实。 calculateOffset方法是为了将来的实现。

我做过实验,每次只写标题。当设置为不附加时它可以完美地工作。正如预期的那样,当它设置为追加时,它将添加多个 header 。

尝试添加 4 条记录后,我现在从文件中得到的结果只有 2 行。标题很完美,没有任何问题。然而,所有 4 条记录都写入下一行并相互覆盖。

生成的调试文本:

  1. 写作记录@6
  2. 写作记录@12
  3. 写作记录@18
  4. 写作记录@24
  5. 阅读记录@6
  6. 3457

所有记录位置都是正确的,但是“3457”是同一行上所有 4 条记录被覆盖的结果。

最佳答案

如果您想写入文件中的多个点,您确实应该考虑使用 RandomAccessFile ,就是为此目的而设计的。

更新:您还应该对所有写入使用相同的 RandomAccessFile 实例,而不是每次更新 header 或内容时单独创建一个实例。

关于java - FileOutputStream 在追加和覆盖之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26158728/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com