我试图打开并显示一个包含多个对象的文件(数组)。我能够打开一个文件并只显示文件中的第一个对象,但我希望能够在文件中打开并显示所有对象。
以下是我尝试的方法:
public T BinaryFileDeSerialize<T>(string filePath)
{
FileStream fileStream = null;
Object obj;
try
{
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
fileStream = new FileStream(filePath, FileMode.Open);
BinaryFormatter b = new BinaryFormatter(); obj = b.Deserialize(fileStream);
}
catch
{
throw;
}
finally
{
if (fileStream != null)
fileStream.Close();
}
return (T)obj;
}
MainForm
:
private Animal ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
Animal str = BinSerial.BinaryFileDeSerialize<Animal>(filename);
return str;
}
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = openFileDialog1.FileName;
Animal msg = ReadFile(thefilename);
if (msg != null)
{
Resultlst.Items.Add(msg);
}
else
UpdateResults();
}
}
我没有收到任何错误。问题是它打开并只显示文件中的第一个对象。我希望它打开并显示该文件中的所有对象。
更新
这是我序列化它的方式:
public void BinaryFileSerialize(object[] objs, string filePath)
{
FileStream fileStream = null;
try
{
fileStream = new FileStream(filePath, FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
foreach (var obj in objs)
{
b.Serialize(fileStream, obj);
}
}
catch
{
throw;
}
finally
{
if (fileStream != null)
fileStream.Close();
}
}
更新2:
public T BinaryFileDeSerialize<T>(string filePath)
{
FileStream fileStream = null;
Object obj;
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
using (var thefileStream = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter b = new BinaryFormatter();
obj = b.Deserialize(thefileStream);
}
return (T)obj;
}
private Animal[] ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
var animals = BinSerial.BinaryFileDeSerialize<Animal[]>(filename);
return animals;
}
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = openFileDialog1.FileName;
Animal []msg = ReadFile(thefilename);
if (msg != null)
{
Resultlst.Items.Add(msg);
}
else
UpdateResults();
}
我收到错误:
无法将Namespace.Animal类型的对象转换为type System.Collections.Generic.List`1 [Namespace.Animal]。
错误来自此return (T)obj;
答案 0 :(得分:1)
如果要使用当前的序列化程序,则应更改反序列化方法,如下所示:
public IList<T> BinaryFileDeSerialize<T>(string filePath) where T: class
{
var list = new List<T>();
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
using(var fileStream = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter b = new BinaryFormatter();
while(fileStream.Position < fileStream.Length)
list.Add((T)b.Deserialize(fileStream));
}
return list;
}
ReadFile应该是这样的:
private Animal[] ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
var animals = BinSerial.BinaryFileDeSerialize<Animal>(filename);
return animals.ToArray();
}
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = openFileDialog1.FileName;
var messages = ReadFile(thefilename);
if (messages != null)
{
messages.ToList().ForEach(msg =>
Resultlst.Items.Add(msg));
}
else
{
UpdateResults();
}
}
}
答案 1 :(得分:0)
愚蠢的问题,但如果您序列化为List<Animal>
然后尝试拨打BinaryFileDeSerialize<List<Animal>>()
会怎样?
此外,您可以使用using语句简化您的方法。
public T BinaryFileDeSerialize<T>(string filePath)
{
FileStream fileStream = null;
Object obj;
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
using(var fileStream = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter b = new BinaryFormatter();
obj = b.Deserialize(fileStream);
}
return (T)obj;
}
编辑:
尝试对代码进行这些调整......
//call via BinaryFileSerialize<Animal>(..., ...);
public void BinaryFileSerialize<T>(T[] objs, string filePath)
{
using(var fileStream = new FileStream(filePath, FileMode.Create))
{
BinaryFormatter b = new BinaryFormatter();
b.Serialize(fileStream, objs);
}
}
private Animal[] ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
var animals = BinSerial.BinaryFileDeSerialize<Animal[]>(filename);
return animals;
}