反序列化(二进制)

我正在创建一个查看器。 第一次进入目录时,通过处理文件,精确图像和序列化数据到数据文件来创建数据文件。 然后,我将该新创建的文件反序列化为要查看的表单。 第二次进入目录时,它会看到该文件尝试将其反序列化以填充表单。 系统需要首先创建时才能正常工作,但如果已经存在,我会收到未引用的对象错误。 我错过了什么?

 private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            listView1.Items.Clear();
            fileInfoList.Clear();
            //fileNameList.Clear();
            ClearFlowPanel();

            TreeNode newSelected = e.Node;
            DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;

            dirPath = nodeDirInfo.FullName;
            label_selectedPath.Text = dirPath;

            foreach (FileInfo file in nodeDirInfo.GetFiles("*.sbs", option))
            {
                if (file.Extension == ".sbs")
                {
                    fileInfoList.Add(file);

                }
            }

            foreach (FileInfo info in fileInfoList)
            {
                ListViewItem i = listView1.Items.Add(info.Name, 1);
                i.SubItems.Add(SizeInKB(info.Length));
                i.SubItems.Add(info.LastWriteTime.ToShortDateString());
            }
            listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

            string binData = dirPath + "" + ".browser" + "" + "_browser.bin";
            if (File.Exists(binData))
            {
                DeserializeData(binData); //creates error
            }
        }

        private void DeserializeData(string binPath)
        {
            FileStream fs = new FileStream(binPath, FileMode.Open);
            BinaryFormatter bin = new BinaryFormatter();

            int length = (int)bin.Deserialize(fs);

            MessageBox.Show(length.ToString());

            for (int i = 0; i < length; i++)
            {
                viewerData[i] = (ViewerData)bin.Deserialize(fs); //problem
            }

            for (int i = 0; i < viewerData.Length; i++)
            {
                PopulateFlowControl(viewerData[i]);
                viewerNameList.Add(viewerData[i].name);
            }
        }

        private void UpdateDirectory()
        {
            thumbPath = dirPath + "" + ".browser";
            if (!Directory.Exists(thumbPath))
            {
                Directory.CreateDirectory(thumbPath);
            }

            fileInfoArray = fileInfoList.ToArray();
            viewerData = new ViewerData[fileInfoArray.Length];

            string binData = thumbPath + "" + "_browser.bin";
            Stream stream = File.Open(binData, FileMode.Create);
            BinaryFormatter bin = new BinaryFormatter();
            bin.Serialize(stream, fileInfoArray.Length);

            ProgressBar_Form progressBar = new ProgressBar_Form(fileInfoArray.Length);
            progressBar.Show();

            for (int i = 0; i < fileInfoArray.Length; i++)
            {
                viewerData[i] = new ViewerData(fileInfoArray[i]);
                bin.Serialize(stream, viewerData[i]);

                progressBar.progressBar1.PerformStep();
                progressBar.label_progress.Text = "Processing : " + fileInfoArray[i].Name;

                viewerData[i].image.Dispose();

                if (File.Exists(viewerData[i].imagePath))
                {
                    File.Delete(viewerData[i].imagePath);
                }
            }

            stream.Close();
            progressBar.Close();

            DeserializeData(binData); //works fine
        }

编辑:

错误:对象引用未设置为对象的实例 - 在DeserializeData的第一个for循环中的行注释“问题”(string binPath);

堆栈跟踪...

在X: Visual Studio 2010 Projects Substance Designer Substance_Browser_12 Substance_Browser_12 Form1.cs中Substance_Browser_12.Form1.DeserializeData(String binPath):Substance_Browser_12.Form1.treeView1_NodeMouseClick处的第151行(对象发件人,TreeNodeMouseClickEventArgs e) Visual Studio 2010 Projects Substance Designer Substance_Browser_12 Substance_Browser_12 Form1.cs:系统上System.Windows.Forms.TreeView.OnNodeMouseClick处的第133行System.Windows.Forms.TreeView.WmNotify(Message&m)处的TreeNodeMouseClickEventArgs e。在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息&m)在System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息&m)在System.Windows.Forms的Windows.Forms.TreeView.WndProc(消息&m)。在System.Windows.Forms.Control.SendMessage上System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd,Int32 msg,IntPtr wParam,IntPtr lParam)上的NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) Int32味精, IntPtr wparam,IntPtr lparam)at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd,Message&m)at System.Windows.Forms.Control.WmNotify(Message&m)at System.Windows.Forms.Control.WndProc(Message&m )System.Windows.Forms.ScrollableControl.WndProc(Message&m)at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)at System。 System.Windows.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc,IntPtr hWnd,Int32 msg,IntPtr wParam,IntPtr lParam)上的Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) System.Windows.Forms上的System.Windows.Forms.TreeView.WmMouseDown(Message&m,MouseButtons按钮,Int32点击)上的System.Windows.Forms.Control.DefWndProc(Message&m)上的.Forms.NativeWindow.DefWndProc(Message&m) .TreeView.WndProc(Message&m)at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&gt;)System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID,Int32 reason,Int32 pvLoopData)at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext上下文)在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32原因,ApplicationContext上下文)在System.Windows.Forms.Application.Run(Form mainForm)在Substance_Browser_12.Program.Main()在X: Visual Studio中(System.AppDomain.ExecuteAssembly(String assemblyFile,E 在System.ThreadingHelper.ThreadStart_Context(对象状态)在System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback回调,对象状态,在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()videance程序集安全,字符串[] args)在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)System.Threading.ThreadHelper.ThreadStart上System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态,布尔preserveSyncCtx)上的布尔preserveSyncCtx) ()


在msdn BinaryFormatter.Deserialize方法(流)

对于成功的反序列化,流中的当前位置必须位于对象图的开头。

所以可能当你尝试反序列化流中的当前位置时不在对象图的开头。


您正在将多个ViewerData对象序列化为一个文件,但文件中没有这些对象的容器。 我不认为BinaryFormatter支持这种用法。 序列化这些对象的替代方法:

  • 为每个文件序列化一个ViewerData。
  • 将所有ViewerData对象添加到集合中,然后将集合序列化。 如果存在许多大图像,则可能会出现内存不足错误。
  • 开发一种将BinaryFormatter与手动写入/读取相结合的算法,以避免使用过多的内存。 这可能需要一个中间流,例如用于序列化每个ViewerData的MemoryStream 。 请参阅下面的伪代码步骤。
  • 将对象的计数写入文件流。
    对于每个对象。 使用BinaryFormatter对MemoryStream进行序列化。 将MemoryStream的长度写入文件流。 将MemoryStream写入文件流

    然后做相反的反序列化对象。


    我需要在DeserializeData(string binPath)中重新初始化viewerData。 如果它来自UpdateDirectory()它已经是。

    viewerData = new ViewerData[length];
    

    谢谢各位的意见!

    链接地址: http://www.djcxy.com/p/93505.html

    上一篇: Deserialize (binary)

    下一篇: got the exception Object reference not set to an instance of an object