1

我正在打开一个存储了我所有记录的序列化文件。该代码在当前记录的对象 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)
{

    ??????

 }
4

2 回答 2

2

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

于 2011-11-30T19:26:36.750 回答
1

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

不同大小的记录

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

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

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

这将创建一个与旧文件具有相同内容的新文件,只是您跳过了要删除的记录。

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

  1. 打开一个新的流
  2. 反序列化旧流中的项目
  3. 如果要保留它,请将其序列化回新流中
  4. 其余的项目以此类推。

固定大小的记录

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

于 2011-11-30T19:21:09.147 回答