Golang遍历目录并删除文件或目录的方法
Golang遍历目录并删除文件或目录的方法 我将大量文件复制到了一个已存在的目录中,现在需要撤销此操作。目标目录中包含许多其他文件,这些文件需要保留,因此无法简单地删除目录中的所有文件。我使用Python成功完成了此操作。以下是脚本:
import os, sys, shutil
source = "/tmp/test/source"
target = "/tmp/test/target"
for root, dirs, files in os.walk(source): # for files and directories in source
for dir in dirs:
if dir.startswith("."):
print(f"Removing Hidden Directory: {dir}")
else:
print(f"Removing Directory: {dir}")
try:
shutil.rmtree(f"{target}/{dir}") # remove directories and sub-directories
except FileNotFoundError:
pass
for file in files:
if file.startswith("."): # if filename starts with a dot, it's a hidden file
print(f"Removing Hidden File: {file}")
else:
print(f"Removing File: {file}")
try:
os.remove(f"{target}/{file}") # remove files
except FileNotFoundError:
pass
print("Done")
上述脚本会检查原始(源)目录并列出其中的文件。然后,它会检查您复制文件的目标目录,并仅删除源目录中存在的已列出文件。
如何在Golang中实现相同的功能?我尝试使用filepath.WalkDir(),但文档中说明:
WalkDir walks the file tree rooted at root, calling fn for each file or directory in the tree, including root.
如果WalkDir()包含根目录,那么os.Remove或os.RemoveAll将会删除整个目录。
更多关于Golang遍历目录并删除文件或目录的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
找到了答案。使用 os.ReadDir 读取源目录条目。对于每个条目,使用 os.RemoveAll 删除对应的目标文件。
func main() {
fmt.Println("hello world")
}
更多关于Golang遍历目录并删除文件或目录的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang中实现类似功能,可以使用filepath.WalkDir()遍历源目录,然后删除目标目录中对应的文件和目录。关键是要正确处理相对路径,避免删除整个目标目录。
以下是实现代码:
package main
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
)
func main() {
source := "/tmp/test/source"
target := "/tmp/test/target"
err := filepath.WalkDir(source, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
// 获取相对于源目录的相对路径
relPath, err := filepath.Rel(source, path)
if err != nil {
return err
}
// 跳过源目录本身
if relPath == "." {
return nil
}
// 构建目标路径
targetPath := filepath.Join(target, relPath)
if d.IsDir() {
// 处理目录
if strings.HasPrefix(d.Name(), ".") {
fmt.Printf("Removing Hidden Directory: %s\n", d.Name())
} else {
fmt.Printf("Removing Directory: %s\n", d.Name())
}
// 删除目录及其内容
if err := os.RemoveAll(targetPath); err != nil && !os.IsNotExist(err) {
return err
}
} else {
// 处理文件
if strings.HasPrefix(d.Name(), ".") {
fmt.Printf("Removing Hidden File: %s\n", d.Name())
} else {
fmt.Printf("Removing File: %s\n", d.Name())
}
// 删除文件
if err := os.Remove(targetPath); err != nil && !os.IsNotExist(err) {
return err
}
}
return nil
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println("Done")
}
对于更精确的控制,可以使用以下版本,它先收集所有需要删除的路径,然后按深度逆序删除(先删除最深层的文件/目录):
package main
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
)
func main() {
source := "/tmp/test/source"
target := "/tmp/test/target"
var paths []string
// 第一步:收集所有需要删除的路径
err := filepath.WalkDir(source, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
relPath, err := filepath.Rel(source, path)
if err != nil {
return err
}
if relPath == "." {
return nil
}
targetPath := filepath.Join(target, relPath)
paths = append(paths, targetPath)
return nil
})
if err != nil {
fmt.Printf("Error collecting paths: %v\n", err)
return
}
// 第二步:按路径深度逆序排序(先删除最深层的)
sort.Slice(paths, func(i, j int) bool {
return len(strings.Split(paths[i], string(os.PathSeparator))) >
len(strings.Split(paths[j], string(os.PathSeparator)))
})
// 第三步:删除所有收集的路径
for _, path := range paths {
if info, err := os.Stat(path); err == nil {
if info.IsDir() {
if strings.HasPrefix(filepath.Base(path), ".") {
fmt.Printf("Removing Hidden Directory: %s\n", filepath.Base(path))
} else {
fmt.Printf("Removing Directory: %s\n", filepath.Base(path))
}
if err := os.RemoveAll(path); err != nil && !os.IsNotExist(err) {
fmt.Printf("Error removing directory %s: %v\n", path, err)
}
} else {
if strings.HasPrefix(filepath.Base(path), ".") {
fmt.Printf("Removing Hidden File: %s\n", filepath.Base(path))
} else {
fmt.Printf("Removing File: %s\n", filepath.Base(path))
}
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
fmt.Printf("Error removing file %s: %v\n", path, err)
}
}
}
}
fmt.Println("Done")
}
这两个实现都只删除源目录中存在的文件和目录,不会影响目标目录中的其他文件。使用filepath.Rel()获取相对路径是关键,这样可以正确构建目标路径而不包含源目录本身。

