【问题标题】:WPF Polyline disk binary serializationWPF折线磁盘二进制序列化
【发布时间】:2015-11-21 22:45:21
【问题描述】:

在 WPF 中,我需要对具有大量点的折线变量进行二进制序列化。我使用以下代码:

SaveFileDialog sf = new SaveFileDialog();
sf.FileName = "Orig.txt"); 

if (sf.ShowDialog() == true)
{
    FileStream fs = new FileStream(sf.FileName, FileMode.Create);
    BinaryFormatter formatter = new BinaryFormatter();

    try
    {
        formatter.Serialize(fs, plOriginal);
    }
    catch (Exception exc)
    {
        MessageBox.Show("Failed to serialize. Reason: " + exc.Message);
    }

    fs.Close();
}

但我得到了错误:

System.Runtime.Serialization.SerializationException:类型 程序集“PresentationCore”中的“System.Windows.Media.PolyLineSegment”, 版本=3.0.0.0,文化=中性,PublicKeyToken=31bf3856ad364e35' 是 未标记为可序列化。在 System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType 类型)在 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(类型 类型,StreamingContext 上下文)在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() 在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(对象 obj,ISurrogateSelector surrogateSelector,StreamingContext 上下文, SerObjectInfoInit serObjectInfoInit,IFormatterConverter 转换器, ObjectWriter objectWriter) 在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(对象 图,Header[] inHeaders,__BinaryWriter serWriter,布尔 fCheck)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(流 序列化流、对象图、Header[] 标头、布尔 fCheck)
在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(流 序列化流,对象图)在 CurveAnalyzerDemoWPF.MainWindow.rbSave_Click(对象发送者, RoutedEventArgs e) 在 MainWindow.xaml.cs:line 92}

那么有什么解决方法可以让它工作吗? 提前谢谢

编辑:我将可序列化属性放在折线变量上:

[Serializable]
private PolyLineSegment plOriginal = new PolyLineSegment();

但我得到以下编译错误: 错误 1 ​​属性“Serializable”在此声明类型上无效。它仅对“类、结构、枚举、委托”声明有效。 F:\C# WPF\CurveAnalyzerDemoWPF\CurveAnalyzerDemoWPF\MainWindow.xaml.cs 55 4 CurveAnalyzerDemoWPF

【问题讨论】:

    标签: wpf serialization binary


    【解决方案1】:

    该消息是不言自明的。要使用二进制格式化程序目标类必须用[Serializable] 属性标记。我建议您序列化数据而不是 3rd 方类实例。 您可以使用 [Seraliable] 属性创建自己的类来存储点坐标,从中构建折线并在需要时更新其数据。然后序列化你自己的类。

    CS:

    public partial class MainWindow : Window
    {
        PolyLineData dataStorage = new PolyLineData();
    
        public MainWindow()
        {
            InitializeComponent();
            PopulateFromXaml();
            SaveToFile();
            LoadFromFile();
            PopulateToXaml();
        }
    
        private void PopulateToXaml()
        {
            polyLine.Points = new PointCollection(dataStorage.Points);
        }
    
        public void SaveToFile()
        {
            SaveFileDialog sf = new SaveFileDialog();
            sf.FileName = "Orig.txt";
            if (sf.ShowDialog() == true)
            {
                FileStream fs = new FileStream(sf.FileName, FileMode.Create);
                BinaryFormatter formatter = new BinaryFormatter();
                try
                {
                    formatter.Serialize(fs, dataStorage);
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Failed to serialize. Reason: " + exc.Message);
                }
                fs.Close();
            }
        }
    
        public void LoadFromFile()
        {
            OpenFileDialog of = new OpenFileDialog();
            if ((bool)of.ShowDialog())
            {
                FileStream fs = new FileStream(of.FileName, FileMode.Open);
                BinaryFormatter bf = new BinaryFormatter();
                dataStorage = bf.Deserialize(fs) as PolyLineData;
                fs.Close();
            }
        }
    
        public void PopulateFromXaml()
        {
            foreach (var item in polyLine.Points)
            {
                dataStorage.Points.Add(item);
            }
        }
    
        [Serializable]
        public class PolyLineData
        {
            public List<Point> Points = new List<Point>();
        }
    }
    

    XAML:

     <Grid>
        <Polyline Stroke="LightBlue" 
                  StrokeThickness="4" 
                  Name="polyLine"
                  Points="10,150 30,140 50,170 70,120 90,190 110,100 130,210 150,80 170,230 190,60 210,250 230,150 320,150" />
     </Grid>
    

    【讨论】:

    • 感谢您的回答一百万。正如您在我的编辑中看到的那样,我已经尝试设置序列化程序属性。它没有用。您的解决方案非常出色,我已经考虑过了,但是因为我要处理 10^6 分。所以它可能很耗时(虽然不是那么多)。所以我更愿意找到一种解决方法来标记它可序列化。我不应该这样做吗?我会按照你的解决方案。
    • @Patrick 这是因为必须在类定义中设置此属性。由于 PolyLine 不是您创建的课程,因此您无法轻松完成。
    • 嗯,我不认为这种方法会增加很多执行时间,但你可以测试一下。您可以尝试使用 3rd 方序列化程序。其中一些可能比二进制终结器工作得更快。通过序列化 PolyLine,您实际上将序列化它的所有字段和属性。它实际上有 98 个属性,因为它是一个 WPF 对象
    • @Patrick 底线是:您应该序列化数据,而不是 WPF System.Windows.Shapes.Polyline。
    • @nethaolic 你说得对!!在 I7 上的硬盘上序列化 10^6 点需要 2.5 秒,其中 40ms 的数据传输和 1.96' 的磁盘保存。你能推荐一个好的第三方序列化器吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 2016-07-27
    • 1970-01-01
    相关资源
    最近更新 更多