序列化和反序列化多个对象

5
我正在制作一个错误日志库,该库会在指定位置创建一个文件,然后将错误信息保存在该文件中,随后可以通过我打算与此库一起编写的独立任务程序来读取该文件。
我使用二进制格式(使用BinaryFormatter()和FileStream())进行保存,其中我将名为ErrorEntry的类序列化到文件中,并将其附加到文件末尾。这意味着我有一系列的ErrorEntries相继而行。我没有将其作为列表,因为从文件中读取所有信息并添加条目,然后将其保存回文件并清除资源似乎不太实用。只需执行单个写入命令即可,将每个对象作为自己的序列化对象存储似乎更有效。
我的问题是,我可以找到多个序列化列表或单个对象的示例,但没有关于多个但分离的对象的内容。虽然我想将它们保存为单独的对象,但当我加载它们时,我想读取对象并返回该对象的系列作为一个列表。我想象有类似的东西。
while(!EOF)
{
     //deserialize each object
     //add individual object to a list
}
//return the list of objects

我该如何从一个文件中反序列化每个对象?它是否具有内部标记来判断读取操作是否完成,或者我需要采取其他措施来读取它们?请注意不要删除任何HTML标签。

为什么不把所有这些对象放入一个 List<object> 中并序列化该数据结构呢?这样可以避免许多角落情况,例如被认为是“独立”的对象之间的相互依赖。 - Ondrej Tucny
@OndrejTucny想要在不加载所有先前条目的情况下将内容附加到文件中。 - weston
他说为什么,并且看起来很合理。要在对象级别上进行反序列化,您必须在每个条目后编写分隔符序列,并在读取文件时对其做出反应。 - Tommi
1个回答

6

使用 FileStream fs; ,您可以使用 fs.Position!=fs.Length 来检测文件结尾。

在追加时,使用 FileMode.Append 或者 fs.Seek(0, SeekOrigin.End); 在写入新条目之前跳到末尾。

完全反序列化:

public static ICollection<T> DeserializeList<T>(FileStream fs)
{
    BinaryFormatter bf = new BinaryFormatter();
    List<T> list = new List<T>();
    while(fs.Position!=fs.Length)
    {
         //deserialize each object in the file
         var deserialized = (T)bf.Deserialize(fs); 
         //add individual object to a list
         list.Add(deserialized);
    }
    //return the list of objects
    return list;
}

1
从这个文件反序列化对象怎么样?使用追加可以将许多对象序列化到文件中,并不保证您能够将它们反序列化回来。 - Artemix
@Artemix 看一下修改。根据他在问题中的代码,有什么问题吗? - weston
只使用filemode.append然后写入会起作用吗?还是我需要同时使用filemode.append和fs.seek? - David Torrey
我会测试一下并让你知道是否一切顺利。 - David Torrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接