vb.net - 递归地将 ZIP 文件结构转换为树视图
问题描述
我一直想知道是否有办法让我的代码以递归方式运行。
我确实在 Stack Overflow 上看过一些示例,但它们似乎都只处理本地驱动器上的现有文件结构。
Zip 文件没有文件结构。只有完整路径的列表。
在我因为没有发布任何编码尝试而受到抨击之前,我不知道该怎么做。递归是一种巫术魔法,如果没有示例工作,我永远无法正确编码。
以下是我制定的解决方案。如果有人一直试图解决这个问题..试试这个。它可以工作,但只能处理 8 层嵌套。一旦您了解了代码的工作原理,它就可以很容易地扩展。
如果可以将其转换为更紧凑且可能更快的东西,我想尝试在一些指导下对其进行编码。
Module modZipFolderResolver
Public root As root_
Public Structure root_
Public node() As root_
Public name As String
Public index As Integer
Public isDir As Boolean
Public count As Integer
Dim n As TreeNode
Public Function find(f As String, ByRef idx As Integer)
If node Is Nothing Then
Return False
End If
For k = 0 To Me.node.Length - 1
If node(k).name = f Then
idx = k
Return True
End If
Next
Return False
End Function
Public Sub add(ByRef s As String, ByRef idx As Integer, ByVal fullname As String, ByRef p_node As TreeNode, ByVal isDir As Boolean)
ReDim Preserve Me.node(Me.count + 1)
idx = Me.count
node(Me.count) = New root_
node(Me.count).name = s
'------------------------------------
'add node
Dim nn As New TreeNode 'create new treevire node
nn.Tag = fullname
nn.Text = Me.node(Me.count).name
If isDir Then ' set image index based on type
Me.node(Me.count).isDir = True
nn.SelectedImageIndex = 2
nn.ImageIndex = 2
nn.Name = "dir" 'used for evauation when clicked
Else
Me.node(Me.count).isDir = False
nn.SelectedImageIndex = 1
nn.ImageIndex = 0
nn.Name = ""
End If
'------------------------------------
' make a new one if its blank
If p_node Is Nothing Then
p_node = New TreeNode
p_node.Text = Me.name
End If
Me.node(Me.count).n = New TreeNode
Me.node(Me.count).n = nn
p_node.Nodes.Add(Me.node(Me.count).n)
'------------------------------------
Me.count += 1
End Sub
End Structure
Public Sub build_tree()
'--------------------------------------------------------
'create the root node
root = New root_
GC.Collect() ' clean up garbage if we just killed existing data
root.n = New TreeNode
root.n.SelectedImageIndex = 2
root.n.ImageIndex = 2
root.n.Text = frmTreeList.tv_filenames.SelectedNode.Text
root.n.Name= "dir"
frmTreeList.tv_contents.Nodes.Add(root.n) 'Add to treeview
'--------------------------------------------------------
'now the fun up part. Create the nested tree structure.
Dim indexes(9) As Integer 'used to keep track of where we are in the tree structure
Dim isDir As Boolean = False ' flag for setting up image index
For Each ent In current_package
Dim ext = Path.GetExtension(ent.FileName)
If ext.Length > 0 Then 'is this entry a file or directory?
isDir = False
Else
isDir = True
End If
Dim a = ent.FileName.Split("/")
For i = 0 To 8 ' 8 levels deep enough?
If a.Length = 2 Then
Exit For
End If
If i > a.Length - 1 Then
Exit For
End If
For k = i To a.Length - 1
If a(k) = "" Then
Exit For
End If
Dim idx As Integer
Select Case k
Case 0
If root.find(a(0), idx) Then
indexes(0) = idx
Else
root.add(a(0), idx, ent.FileName, root.n, isDir)
indexes(0) = idx
Exit For
End If
Case 1
If root.node(indexes(0)).find(a(1), idx) Then
indexes(1) = idx
Else
Dim n = root.node(indexes(0)).n
root.node(indexes(0)).add(a(1), idx, ent.FileName, n, isDir)
indexes(1) = idx
Exit For
End If
Case 2
If root.node(indexes(0)).node(indexes(1)).find(a(2), idx) Then
indexes(2) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).n
root.node(indexes(0)).node(indexes(1)).add(a(2), idx, ent.FileName, n, isDir)
indexes(2) = idx
Exit For
End If
Case 3
If root.node(indexes(0)).node(indexes(1)).node(indexes(2)).find(a(3), idx) Then
indexes(3) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).node(indexes(2)).n
root.node(indexes(0)).node(indexes(1)).node(indexes(2)).add(a(3), idx, ent.FileName, n, isDir)
indexes(3) = idx
Exit For
End If
Case 4
If root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).find(a(4), idx) Then
indexes(4) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).n
root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).add(a(4), idx, ent.FileName, n, isDir)
indexes(4) = idx
Exit For
End If
Case 5
If root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).find(a(5), idx) Then
indexes(5) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).n
root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).add(a(5), idx, ent.FileName, n, isDir)
indexes(5) = idx
Exit For
End If
Case 6
If root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).find(a(6), idx) Then
indexes(6) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).n
root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).add(a(6), idx, ent.FileName, n, isDir)
indexes(6) = idx
Exit For
End If
Case 7
If root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).node(indexes(6)).find(a(7), idx) Then
indexes(7) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).node(indexes(6)).n
root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).node(indexes(6)).add(a(7), idx, ent.FileName, n, isDir)
indexes(7) = idx
Exit For
End If
Case 8
If root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).node(indexes(6)).node(indexes(7)).find(a(8), idx) Then
indexes(8) = idx
Else
Dim n = root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).node(indexes(6)).node(indexes(7)).n
root.node(indexes(0)).node(indexes(1)).node(indexes(2)).node(indexes(3)).node(indexes(4)).node(indexes(5)).node(indexes(6)).node(indexes(7)).add(a(8), idx, ent.FileName, n, isDir)
indexes(8) = idx
Exit For
End If
End Select
Next 'k
Next 'i
Next 'each ent
End Sub
End Module
解决方案
就算法而言,我会这样做: -
对于每个路径: - 通过“/”字符将路径拆分为字符串数组。将此数组连同根节点和索引 0 一起传递到一个新函数中,以指示您要到达的位置。
该函数应该: - 获取传入的索引的路径分量 查找或在作为参数传入的节点内创建与路径分量匹配的子节点 如果传入的索引等于路径分量数组的长度 -1然后返回找到/创建的子节点否则该函数应返回对自身的调用结果,传入子节点和传入+1的索引
此函数应根据需要创建节点并返回路径的节点
推荐阅读
- smtp - 在 GitLab 11.4.4-ee 中更改通知邮件发件人姓名
- java - 进行二进制搜索时出现 java.lang.ArrayIndexOutOfBoundsException 错误?
- javascript - Typescript - 如何提取对象数组中的对象?
- php - 更改年份时找不到php抛出页面中的日历
- php - CI中的MySQL PHP查询
- python - 如何根据 csv 文件条目的数量动态创建 tkinter 按钮
- mysql - 验证日期 mySQL
- javascript - 打字稿功能类型推断
- tensorflow - 使用 `tf.data` 有效统计 TFRecords 中的示例数?
- python - Python 3 继承问题