从序列化文件中删除记录?

时间:2011-11-30 19:14:24

标签: c# filestream binaryformatter

我正在打开一个存储了所有记录的序列化文件。代码查找当前记录的对象ID号属性与相应文本框中的数字之间的匹配。如果匹配,我想删除记录。最好的方法吗?

Item readItem = new Item();
BinaryFormatter bFormatter = new BinaryFormatter();
FileStream inFile = new FileStream(@"C:\file.dat", FileMode.Open, FileAccess.Read);

while (inFile.Position < inFile.Length)
    readItem = (Item)bFormatter.Deserialize(inFile);
    if (readItem.ID.ToString() == IDTextBox.Text)
{

    ??????

 }

2 个答案:

答案 0 :(得分:2)

您需要反序列化文件,从列表中删除项目,然后重新序列化整个项目。最好使用像SQLLite这样的基于文件的数据库,只需将记录序列化为行内的blob。

答案 1 :(得分:1)

这取决于您是否有固定大小的记录或不同大小的记录。

不同大小的记录

那么,您需要做的是在您想要删除的记录之后移动文件的所有内容,覆盖要删除的部分,然后截断文件。这有点难以就地(即在同一个文件中),因为您只能读取足够的数据以避免在每次上移循环时覆盖文件的其余部分。

将从旧文件创建新文件的更简单方法如下:

  1. 在反序列化项目之前记下流的位置
  2. 如果项目匹配,请记下当前流的位置(现在两个位置描绘了您要删除的记录所在的文件区域)
  3. 创建一个新文件,并从头开始,首先从旧流(您找到该记录的流)到新流
  4. 复制与第一个位置相同的字节数。
  5. 将旧流放置在您找到的记录之后 之后的位置,并将您可以找到的所有内容复制到新流中
  6. 这将创建一个与旧文件具有相同内容的新文件,除了您跳过要删除的记录。

    如果您可以遍历所有记录并简单地确定是否要保留它,这是一个更简单的方法:

    1. 打开新流
    2. 反序列化旧流中的项
    3. 如果您想保留它,请将其序列化为新流
    4. 等等其他项目。
    5. 固定大小记录

      只需读取文件的最后一条记录,将文件放回到要删除的记录的位置,然后用刚才读取的最后一条记录的内容覆盖它,然后在最后一条记录之前截断文件记录文件。