【问题标题】:why XML-serialization isn't working为什么 XML 序列化不起作用
【发布时间】:2016-03-28 14:12:33
【问题描述】:
public class StorageOfData
{
    public static StorageOfData instance;

    private StorageOfData()
    { }

    public static StorageOfData getInstance()
    {
        if (instance == null)
            instance = new StorageOfData();
        return instance;
    }

    private List<List<VersionOfFile>> list = new List<List<VersionOfFile>>();

    public List<VersionOfFile> this[int index]
    {
        get
        {
            return list[index];
        }
    }

    public void RestoreDataFromFile(String path)
    {
        StorageOfData DATA;
        XmlSerializer mySerializer = new XmlSerializer(typeof(StorageOfData));
        FileStream myFileStream = new FileStream(path + @"BAK\" + "history.xml", FileMode.Open);
        DATA = (StorageOfData)mySerializer.Deserialize(myFileStream);
    }

    public void SaveDataToFile(String path)
    {
        StorageOfData DATA = StorageOfData.getInstance();
        XmlSerializer mySerializer = new XmlSerializer(typeof(StorageOfData));
        StreamWriter myWriter = new StreamWriter(path + @"BAK\" + "history.xml");
        mySerializer.Serialize(myWriter, DATA);
        myWriter.Close();
    }

    public void AddNewEntryIfRenamed(string filename, string real_filename, DateTime date, bool isDeleted)
    {
        for (int i = 0; i < list.Count; i++)
        {

            if (list[i][list[i].Count - 1].Filename == filename)
            {
                list[i].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
                return;
            }
        }
        list.Add(new List<VersionOfFile>());
        list[list.Count - 1].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
    }


    public void AddNewEntryIfCopyExists(string filename, string real_filename, DateTime date, bool isDeleted)
    {
        for (int i = 0; i < list.Count; i++)
        {

            if (list[i][list[i].Count - 1].Filename == filename)
            {
                list[i].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
                return;
            }
        }
        list.Add(new List<VersionOfFile>());
        list[list.Count - 1].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
    }

    public void AddNewEntry(string filename, DateTime date, bool isDeleted)
    {
        for (int i = 0; i < list.Count; i++)
        {

            if (list[i][list[i].Count - 1].Filename == filename)
            {
                list[i].Add(new VersionOfFile(filename, date, isDeleted));
                return;
            }
        }
        list.Add(new List<VersionOfFile>());
        list[list.Count - 1].Add(new VersionOfFile(filename, date, isDeleted));
    }

}

internal struct VersionOfFile
{
    private string filename;
    private string real_filename;
    private DateTime date;
    private bool isDeleted;

    public string Filename
    {
        get
        {
            return filename;
        }
    }

    public string Real_filename
    {
        get
        {
            return real_filename;
        }
    }

    public DateTime Date
    {
        get
        {
            return date;
        }
    }

    public bool IsDeleted
    {
        get
        {
            return isDeleted;
        }
    }

    public VersionOfFile(string filename, string real_filename, DateTime date, bool isDeleted)
    {
        this.filename = filename;
        this.real_filename = real_filename;
        this.date = date;
        this.isDeleted = isDeleted;
    }

    public VersionOfFile(string filename, DateTime date, bool isDeleted)
    {
        this.filename = filename;
        this.date = date;
        this.isDeleted = isDeleted;
        this.real_filename = String.Empty;
    }

我正在编写一个用于备份文件的简单程序,但遇到了问题。 我应该记录任何更改,但是当我尝试序列化有关更改的单音存储信息时,我得到的只是一个空的 .xml 文件。 我应该怎么做才能序列化动态数组(List)??

【问题讨论】:

  • 好的...恕我直言@Byg1 对于“一个简单的程序”,我认为您将事情复杂化了...您能否准确解释您要实现的目标或提供示例您希望看到的 XML ......
  • 要用XmlSerializer序列化你的StorageOfData类,它必须有一个公共的无参数构造函数。你的是私人的。见stackoverflow.com/questions/267724/…。除此之外,您可能还有其他问题。如果这样做,请尝试将您的代码分解为每个问题的minimal, complete examples
  • 另外,XmlSerializer 仅序列化具有公共 getset 的属性。见stackoverflow.com/questions/575432/…。所以你的VersionOfFile 不会正确序列化。
  • @dbc 构造函数不必是公共的,只有无参数的。序列化程序可以通过反射调用它。
  • @Rotem - 看来你是对的:dotnetfiddle.net/Li4dG4。这与here 所述不一致:当您尝试使用 XmlSerializer 类序列化没有公共默认构造函数的类时,您可能会收到 [a] System.InvalidOperationException 异常错误消息 .而在Troubleshooting Common Problems with the XmlSerializerTest.NonSerializable 不能被序列化,因为它没有默认的公共构造函数。

标签: c# xml serialization xmlserializer


【解决方案1】:

另外,一个更简单的方法(我认为这样做),如本视频 (https://www.youtube.com/watch?v=UvEF7UPh1Qg) 中所述,只需创建一个类,您可以在其中指定 xml 文件的元素和属性,然后填充它们并通过代码给它们赋值。

【讨论】:

    【解决方案2】:

    要序列化您的类,您必须为要序列化的数据设置公共读/写属性。

    只需添加

    public List<List<VersionOfFile>> List
        {
            get { return list; }
            set { list = value; }
        }
    

    到 StorageOfData 类并将 setter 添加到 VersionOfFile 结构中的属性。

    PS:

    您的代码未针对您的需要进行优化。尝试保护你的单例类Thread safe Singleton。 对于性能问题,您可以使用 Dictionary>" 并将 [XmlAttribute] 标记添加到结构的属性以减小文件大小。而不是

    <VersionOfFile>
        <Filename>test</Filename>
      </VersionOfFile> 
    

    你会得到

    <VersionOfFile Filename="test"/>
    

    添加Try/Catch Bloc、测试Back Folder是否存在、使用System.IO.Path.Combine添加路径、测试History.xml文件是否存在并在添加新文件之前备份等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多