TreeView序列化为byte[]后反序列化抛出SerializationException求助
TreeView序列化后反序列化失败的解决思路
问题描述
尝试将TreeView转换为byte数组后还原,窗体加载时可正常加载文档结构,序列化过程已实现,但反序列化byte数组还原为TreeView时抛出System.Runtime.Serialization.SerializationException异常。
错误触发代码行
_list = bf.Deserialize(ms) as List<TreeNode>;
完整代码
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { string filepath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); ListDirectory(treeView1, filepath); } private static void ListDirectory(TreeView treeView, string path) { treeView.Nodes.Clear(); var stack = new Stack<TreeNode>(); var rootDirectory = new DirectoryInfo(path); var node = new TreeNode(rootDirectory.Name) { Tag = rootDirectory }; stack.Push(node); while (stack.Count > 0) { var currentNode = stack.Pop(); var directoryInfo = (DirectoryInfo)currentNode.Tag; foreach (var directory in directoryInfo.GetDirectories()) { var childDirectoryNode = new TreeNode(directory.Name) { Tag = directory }; currentNode.Nodes.Add(childDirectoryNode); stack.Push(childDirectoryNode); } foreach (var file in directoryInfo.GetFiles()) currentNode.Nodes.Add(new TreeNode(file.Name)); } treeView.Nodes.Add(node); } private Byte[] SerilizeQueryFilters() { BinaryFormatter bf = new BinaryFormatter(); List<TreeNode> list = new List<TreeNode>(); foreach(TreeNode node in treeView1.Nodes) { list.Add(node); } using (MemoryStream ms = new MemoryStream()) { bf.Serialize(ms, list); return ms.GetBuffer(); } } private void DeSerilizeQueryFilters(byte[] items) { BinaryFormatter bf = new BinaryFormatter(); try { using (MemoryStream ms = new MemoryStream()) { ms.Write(items, 0, items.Length); ms.Position = 0; _list = bf.Deserialize(ms) as List<TreeNode>; treeView2.Nodes.AddRange(_list.ToArray()); } } catch(Exception e) { Console.WriteLine(e.StackTrace); } } private void button1_Click(object sender, EventArgs e) { byte[] data = SerilizeQueryFilters(); DeSerilizeQueryFilters(data); } }
解决思路
1. 核心问题:不可序列化对象导致异常
TreeNode类本身未标记为可序列化,且你给节点Tag属性赋值的DirectoryInfo对象同样不支持二进制序列化,这是触发异常的根本原因。
2. 修复方案:自定义可序列化数据结构
不要直接序列化TreeNode,先将TreeView结构转换为自定义的可序列化类,序列化完成后,反序列化时再重新构建TreeNode。
示例自定义可序列化类:
[Serializable] public class TreeItem { public string Name { get; set; } public bool IsDirectory { get; set; } public string Path { get; set; } // 存储路径而非DirectoryInfo对象,方便反序列化重建 public List<TreeItem> Children { get; set; } = new List<TreeItem>(); }
3. 修改序列化逻辑
将TreeView节点转换为TreeItem后再序列化:
private Byte[] SerilizeQueryFilters() { BinaryFormatter bf = new BinaryFormatter(); // 假设TreeView只有一个根节点 var rootItem = ConvertTreeNodeToTreeItem(treeView1.Nodes[0]); using (MemoryStream ms = new MemoryStream()) { bf.Serialize(ms, rootItem); return ms.ToArray(); // 用ToArray()替代GetBuffer(),避免返回未使用的空字节 } } private TreeItem ConvertTreeNodeToTreeItem(TreeNode node) { var item = new TreeItem { Name = node.Text, IsDirectory = node.Tag is DirectoryInfo }; if (item.IsDirectory) { item.Path = ((DirectoryInfo)node.Tag).FullName; } foreach (TreeNode childNode in node.Nodes) { item.Children.Add(ConvertTreeNodeToTreeItem(childNode)); } return item; }
4. 修改反序列化逻辑
将反序列化得到的TreeItem重新构建为TreeNode:
private void DeSerilizeQueryFilters(byte[] items) { BinaryFormatter bf = new BinaryFormatter(); try { using (MemoryStream ms = new MemoryStream(items)) { var rootItem = bf.Deserialize(ms) as TreeItem; var rootNode = ConvertTreeItemToTreeNode(rootItem); treeView2.Nodes.Clear(); treeView2.Nodes.Add(rootNode); } } catch(Exception e) { Console.WriteLine(e.ToString()); // 打印完整异常信息,便于排查 } } private TreeNode ConvertTreeItemToTreeNode(TreeItem item) { var node = new TreeNode(item.Name); if (item.IsDirectory) { node.Tag = new DirectoryInfo(item.Path); } foreach (var childItem in item.Children) { node.Nodes.Add(ConvertTreeItemToTreeNode(childItem)); } return node; }
5. 额外优化点
- 用
ms.ToArray()替代ms.GetBuffer():GetBuffer()返回MemoryStream的内部缓冲区,包含未使用的空字节,会增大序列化体积且可能引发反序列化异常。 - 异常处理中打印
e.ToString():相比仅打印StackTrace,能获取更完整的错误信息,快速定位问题。 - 存储路径而非
DirectoryInfo对象:避免序列化不可序列化的类型,反序列化时通过路径重建对象更可靠。
内容的提问来源于stack exchange,提问作者Poligamer YT
相关产品推荐
相关产品推荐

