解析完成前遇到的流结束
本文关键字:结束 遇到 | 更新日期: 2023-09-27 18:05:29
我试图从一个文件中读取多个对象,下面的代码:
List<Alarm> list = new List<Alarm>();
BinaryFormatter serializer = new BinaryFormatter();
using (FileStream stream = File.OpenRead("//my File here"))
{
while (stream.Position < stream.Length)
{
list.Add((Alarm)serializer.Deserialize(stream));
}
}
然而,每次我试图运行这段代码,我得到一个错误,如"在解析完成之前遇到的流结束"。请注意,已经有一个线程建议在每次迭代后将流的位置设置为0,但这显然不适合我,否则我会陷入无限循环。
我在这里做错了什么?如果我省略while循环,代码本身就可以工作,但显然,在包含多个对象的文件中,我不想只从文件中获取一个对象,而是要从文件中获取所有对象。
任何建议吗?
编辑:随需应变:
序列化。
//Fetches Data from my GUI, creates a valid Alarm object
Alarm alarm = new Alarm(this.noticeBox.Text, date.Year, date.Month, date.Day, (int)this.hourPicker.Value, (int)this.minutePicker.Value);
var serializer = new BinaryFormatter();
using (FileStream stream = "//file"))
{
serializer.Serialize(stream, alarm);
}
如果您序列化的是Alarm
s的列表(而不是一系列单独的Alarm
s),这是很有可能的,那么您只需要反序列化它:
using (FileStream stream = File.OpenRead("//my File here"))
{
list = (List<Alarm>)serializer.Deserialize(stream));
}
否则,如果你序列化独立的Alarm
对象,你的代码应该工作(他们每个人都将是一个对象图本身,这似乎不是情况)
编辑:你张贴的一切似乎都很好。我在这里添加了一个小提琴(https://dotnetfiddle.net/bGWOOO),它演示了您使用的方法是如何工作的(出于明显的原因,我使用MemoryStream
而不是FileStream
,但这应该无关紧要)。所以还有其他问题:要么流没有正确地写入磁盘,要么没有正确地读取,但这与你发布的代码无关,绝对。
只是为了进一步参考为什么选择这个答案(因为真正的答案在评论/聊天中):
在序列化器中,您每次都创建文件并替换内容(未在问题中显示,但在注释中猜到了),因此答案正确地附加到文件中,如下所示:
using (FileStream stream = new FileStream("** path to file here**", FileMode.Append, FileAccess.Write, FileShare.Write))
{
// write the serialized data to the stream
}
标题>This is a proof of how to serialize / deserialize an object using BinaryFormatter:
List<String> ls = new List<string>();
ls.Add("aaa");
ls.Add("Bb");
BinaryFormatter bf = new BinaryFormatter ();
var fileName = Guid.NewGuid ().ToString ().Replace ("-","");
var path = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData), fileName);
try
{
using (var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
bf.Serialize(fs, ls);
}
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
ls = bf.Deserialize(fs) as List<String>;
}
}
finally
{
if (File.Exists (path))
{
try
{
File.Delete(path);
}
catch
{
}
}
}
看起来您只需要在序列化之前将警报添加到警报列表中。这工作,似乎做你想要的:
void Main()
{
List<Alarm> listYouSerializeInto = new List<Alarm>();
listYouSerializeInto.Add(new Alarm("test", 2015, 07, 29, 06, 00));
listYouSerializeInto.Add(new Alarm("test", 2015, 07, 29, 07, 00));
listYouSerializeInto.Add(new Alarm("test", 2015, 07, 29, 08, 00));
var serializer = new BinaryFormatter();
using (FileStream stream = new FileStream(@"C:'Temp'alarm.bin", FileMode.Create))
{
serializer.Serialize(stream, listYouSerializeInto);
}
List<Alarm> listYouDeserializeInto = new List<Alarm>();
using (Stream stream = new FileStream(@"C:'Temp'alarm.bin", FileMode.Open))
{
listYouDeserializeInto = (List<Alarm>)serializer.Deserialize(stream);
foreach (Alarm a in listYouDeserializeInto)
{
Console.WriteLine(a);
}
}
}
// Define other methods and classes here
[Serializable]
public class Alarm {
public string Text { get; set;}
public int Year { get; set;}
public int Month { get; set;}
public int Day { get; set;}
public int Hour { get; set;}
public int Minute { get; set;}
public Alarm (string text, int year, int month, int day, int hour, int minute)
{
Text = text;
Year = year;
Month = month;
Day = day;
Hour = hour;
Minute = minute;
}
}