首頁 >後端開發 >Golang >從樹中清除僅包含空資料夾的資料夾

從樹中清除僅包含空資料夾的資料夾

WBOY
WBOY轉載
2024-02-09 09:54:101197瀏覽

從樹中清除僅包含空資料夾的資料夾

php小編小新在這裡為大家介紹一個關於資料夾操作的小技巧-如何從樹中清除僅包含空資料夾的資料夾。在日常的文件管理中,我們可能會遇到一些只包含空資料夾的資料夾,這些資料夾佔用了儲存空間,但卻沒有實際的內容。透過以下簡單的操作,我們可以輕鬆清除這些空白資料夾,釋放寶貴的儲存空間,並提高檔案管理的效率。

問題內容

我有一片

type node struct {
   id       string
   children []node
}

我有一個以此切片為模型的目錄結構。該目錄中可能存在多層資料夾結構,最終其中沒有任何檔案。請參閱:ű

folder1/folder2/folder3/folder4
folder1/file1.txt

我想清理那些只有空資料夾的資料夾。因此,在此範例中,只有folder1 中會保留一個文件,下面的所有內容都會被刪除。 但是我似乎想不出這樣做的好主意。我完全可以創建一棵新樹而不改變原始樹,但我不知道如何有效地遍歷這棵樹並查看最後一個孩子是否沒有孩子,然後返回到根並刪除該孩子結果只是一個空文件夾列表。 任何想法都會受到歡迎!

我的初始解決方案僅刪除葉子而不刪除父資料夾:

func removeChildlessFolders(original, tree []Node) []Node {
    for i, node := range original {
        if len(node.Children) == 0 {
            continue
        }

        dir := Node{}
        dir.Id = node.Id
        dir.Children = append(dir.Children, node.Children...)
        tree = append(tree, dir)
        removeChildlessFolders(original[i].Children, node.Children)
    }

    return tree
}

解決方法

首先是個好問題,但其他人很難重現您擁有的用例。從下次開始嘗試添加可重現的程式碼,人們可以使用它並快速測試他們的方法並給出結果。就像您已經傳遞了根但您如何初始化它一樣?如果有人需要幫助你,他們需要先建造一棵樹。一般來說,這是不方便的。儘管如此,讓我們來看看解決方案。

目錄結構

輸入dir

test-folder
├── folder1
│   └── folder2
│       └── folder3
├── folder4
│   ├── folder5
│   └── joker
└── folder6
    └── file.txt

預期結果

test-folder
└── folder6
    └── file.txt

節點定義

首先,我不知道你是如何建立目錄樹的。如果您對它進行了硬編碼,那麼這是一個不同的問題,但是 n-ary 樹通常填充的方式,那麼您需要使用自引用指標定義 node 。不是精確切片。所以我會以以下方式定義節點

type node struct {
    id       string
    children []*node
}

輔助方法

這是一個檢查路徑是否指向目錄的輔助方法

func ifdir(path string) bool {
    file, err := os.open(path)
    if err != nil {
        panic(err)
    }
    defer file.close()
    info, err := file.stat()
    if err != nil {
        panic(err)
    }
    if info.isdir() {
        return true
    }
    return false
}

如何填滿樹

這是使用 queue 輸入 n-ary 樹 的簡單迭代方法。 golang不提供佇列實現,但golang通道其實只是佇列。我將其保留為 500 因為我們無法在 golang 中建立動態緩衝通道。恕我直言,這個數字應該適用於幾乎所有場景。

func buildtreefromdir(basedir string) *node {
    _, err := ioutil.readdir(basedir)
    if err != nil {
        return nil
    }
    root := &node{
        id: basedir,
    }
    //////////
    queue := make(chan *node, 500) // consider that there can not be any dir with > 500 depth
    queue <- root
    for {
        if len(queue) == 0 {
            break
        }
        data, ok := <-queue
        if ok {
            // iterate all the contents in the dir
            curdir := (*data).id
            if ifdir(curdir) {
                contents, _ := ioutil.readdir(curdir)

                data.children = make([]*node, len(contents))
                for i, content := range contents {
                    node := new(node)
                    node.id = filepath.join(curdir, content.name())
                    data.children[i] = node
                    if content.isdir() {
                        queue <- node
                    }
                }
            }
        }
    }
    return root
}

另一種輔助方法

這只是列印目錄樹。僅用於調試目的。

func printdirtree(root *node) {
    fmt.println(root.id)
    for _, each := range root.children {
        printdirtree(each)
    }
    if len(root.children) == 0 {
        fmt.println("===")
    }

}

最後是你的解決方案。

非常簡單。如果您有任何疑問,請告訴我。

func recursiveemptydelete(root *node) {
    // if the current root is not pointing to any dir
    if root == nil {
        return
    }
    for _, each := range root.children {
        recursiveemptydelete(each)
    }
    if !ifdir(root.id) {
        return
    } else if content, _ := ioutil.readdir(root.id); len(content) != 0 {
        return
    }
    os.remove(root.id)
}

這裡是 main()

#
func main() {
    root := buildTreeFromDir("test-folder")
    printDirTree(root)
    recursiveEmptyDelete(root)
}

以上是從樹中清除僅包含空資料夾的資料夾的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除