简介
很多时候会第一时间用linux命令进行文件操作,实际上直接用go的原生函数操作文件更加方便
需求
数据库表记录了需要保留的文件,里面可能是原始文件,也可能是链接文件,需要删除实际目录中其他的文件
- 目录下有A B B1->B C C1->C D
- 数据库有A B1
- 需要删除C1 C D,保留文件A B B1
main.go
- 根据数据库记录的文件名称,获取要保留的文件列表构建map,再遍历目录不在map中的进行删除即可
- 保留文件判断
- 如果是原始文件,保留文件也为原始文件
- 如果是链接文件,保留文件为原始文件和链接文件
package main
import (
"fmt"
"os"
"path/filepath"
)
// keepFileGet 保留文件列表获取
func keepFileGet(path string) []string {
var keepFiles []string
keepFiles = append(keepFiles, filepath.Base(path))
fileInfo, err := os.Lstat(path)
if err != nil {
fmt.Println("err:", err)
}
if fileInfo.Mode()&os.ModeSymlink != 0 {
// 获取软链接指向的目标
target, err := os.Readlink(path)
if err != nil {
fmt.Println("err:", err)
}
keepFiles = append(keepFiles, filepath.Base(target))
}
return keepFiles
}
func main() {
// 指定要处理的目录
dirPath := "./imgs/"
// 初始化
os.Create(dirPath + "A")
os.Create(dirPath + "B")
os.Create(dirPath + "C")
os.Create(dirPath + "D")
os.Symlink("B", dirPath+"B1")
os.Symlink("C", dirPath+"C1")
// 获取数据库中的文件列表
dbFiles := []string{"A", "B1"}
// 获取完整保留文件列表
var keepFiles = make(map[string]bool)
for _, ob := range dbFiles {
kObs := keepFileGet(dirPath + ob)
for _, kob := range kObs {
keepFiles[kob] = true
}
}
fmt.Println("keepFiles:", keepFiles)
// 遍历目录
filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 跳过目录
if info.IsDir() {
return nil
}
_, ok := keepFiles[filepath.Base(path)]
if !ok {
os.Remove(path)
fmt.Println("remove:", path)
}
return nil
})
}
运行
[xiaofeng@localhost fileopr]$ go run main.go
keepFiles: map[A:true B:true B1:true]
remove: imgs/C
remove: imgs/C1
remove: imgs/D
[xiaofeng@localhost fileopr]$
[xiaofeng@localhost fileopr]$ ls -l imgs/
total 0
-rw-rw-r-- 1 xiaofeng xiaofeng 0 Jan 8 15:18 A
-rw-rw-r-- 1 xiaofeng xiaofeng 0 Jan 8 15:18 B
lrwxrwxrwx 1 xiaofeng xiaofeng 1 Jan 8 14:52 B1 -> B
总结
- os.Create 创建文件
- os.Remove 删除文件
- os.Lstat 获取文件信息
- fileInfo.Mode()&os.ModeSymlink != 0 判断是否为链接文件
- fileInfo.IsDir() 判断是否为目录
- filepath.Base() 返回最后元素,如/a/b/c.tar返回c.tar
- filepath.Walk 遍历目录