我正在创建一个观众。第一次进入目录时,可以通过处理文件,修改图像和将数据序列化为数据文件来创建数据文件。然后,我将新创建的文件反序列化为要查看的表单。第二次进入目录时,它会看到文件ans尝试反序列化它以填充表单。系统必须首先创建它才能正常工作,但如果它已经存在,我会收到一个未引用的对象错误。我错过了什么?
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(string binPath)的第一个for循环中注释'problem';
堆栈跟踪......
在X:\ Visual Studio 2010 \ Projects \ Substance Designer \ Substance_Browser_12 \ Substance_Browser_12 \ Form1.cs中的Substance_Browser_12.Form1.DeserializeData(String binPath):第151行 at Substance_Browser_12.Form1.treeView1_NodeMouseClick(Object sender,TreeNodeMouseClickEventArgs e)在X:\ Visual Studio 2010 \ Projects \ Substance Designer \ Substance_Browser_12 \ Substance_Browser_12 \ Form1.cs:第133行 在System.Windows.Forms.TreeView.OnNodeMouseClick(TreeNodeMouseClickEventArgs e) 在System.Windows.Forms.TreeView.WmNotify(消息&amp; m) 在System.Windows.Forms.TreeView.WndProc(消息&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd,Int32 msg,IntPtr wParam,IntPtr lParam) 在System.Windows.Forms.Control.SendMessage(Int32 msg,IntPtr wparam,IntPtr lparam) 在System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd,Message&amp; m) 在System.Windows.Forms.Control.WmNotify(消息&amp; m) 在System.Windows.Forms.Control.WndProc(消息&amp; m) 在System.Windows.Forms.ScrollableControl.WndProc(消息&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc,IntPtr hWnd,Int32 msg,IntPtr wParam,IntPtr lParam) 在System.Windows.Forms.NativeWindow.DefWndProc(消息&amp; m) 在System.Windows.Forms.Control.DefWndProc(消息&amp; m) 在System.Windows.Forms.TreeView.WmMouseDown(消息&amp; m,MouseButtons按钮,Int32点击) 在System.Windows.Forms.TreeView.WndProc(消息&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp; msg) 在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID,Int32 reason,Int32 pvLoopData) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason,ApplicationContext context) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context) 在System.Windows.Forms.Application.Run(Form mainForm) at Substance_Browser_12.Program.Main()在X:\ Visual Studio 2010 \ Projects \ Substance Designer \ Substance_Browser_12 \ Substance_Browser_12 \ Program.cs:第18行 在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String [] args) 在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx) 在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态) 在System.Threading.ThreadHelper.ThreadStart()
答案 0 :(得分:0)
为了成功反序列化,流中的当前位置必须位于对象图的开头。
所以当您尝试反序列化流中的当前位置时,可能不会出现在对象图的开头。
答案 1 :(得分:0)
你只需要改成这个
private void DeserializeData(string binPath)
{
FileStream fs = new FileStream(binPath, FileMode.Open);
fs.Seek(0, SeekOrigin.Begin);
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);
}
}
OR
public static System.IO.MemoryStream Serialize(object _Object)
{
System.IO.MemoryStream _Return = new System.IO.MemoryStream();
Serialize(ref _Return, _Object);
return _Return;
}
public static void Serialize(ref System.IO.Stream Stream, object _Object)
{
BinaryFormatter BF = new BinaryFormatter();
BF.Serialize(Stream, _Object);
}
public static objType Deserialize<objType>(ref System.IO.Stream Stream)
{
object _Return = null;
Stream.Seek(0, SeekOrigin.Begin);
BinaryFormatter BF = new BinaryFormatter();
_Return = BF.Deserialize(Stream);
return (objType)_Return;
}
答案 2 :(得分:0)
您将多个ViewerData对象序列化为一个文件,但文件中没有这些对象的容器。我认为BinaryFormatter
不支持这种用法。序列化这些对象的其他方法:
BinaryFormatter
与手动写入/读取相结合的算法,以避免使用过多的内存。这可能需要一个中间流,例如MemoryStream
用于序列化每个ViewerData。请参阅下面的伪代码步骤。将对象的数量写入文件流 对于每个对象。 使用BinaryFormatter到MemoryStream进行序列化。 将MemoryStream的长度写入文件流。 将MemoryStream写入文件流
然后反过来反序列化对象。
答案 3 :(得分:0)
我需要在DeserializeData(string binPath)中重新初始化viewerData。如果它来自UpdateDirectory()它已经存在。
viewerData = new ViewerData[length];
感谢大家的意见!