打开包含多个对象的文件

时间:2015-04-15 23:03:27

标签: c# file-io visual-studio-2013

我试图打开并显示一个包含多个对象的文件(数组)。我能够打开一个文件并只显示文件中的第一个对象,但我希望能够在文件中打开并显示所有对象。

以下是我尝试的方法:

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;

2 个答案:

答案 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;
    }