gpt4 book ai didi

Go filepath.Walk 挂起

转载 作者:数据小太阳 更新时间:2023-10-29 03:13:00 26 4
gpt4 key购买 nike

我在使用 filepath.Walk() 时遇到了一个奇怪的问题。它开始运行然后到达它刚刚挂起的点。我的 CPU 处于 100%,没有错误,它不会继续。我查看了我正在遍历的目录,它挂起的地方没有什么特别的,没有符号或类似的东西。只是普通的目录和文件。这是我正在使用的代码:

type WatchDirs struct {
Dirs []string
}

//Watches ...Recursively walk the filesystem, entrypoint to file watching
func Watches(tops []string) error {
var dirs WatchDirs
for _, top := range tops {
err := filepath.Walk(top, func(path string, f os.FileInfo, err error) error {
if err != nil {
log.Println(err)
return err
}
log.Println("File: ", path)
if f.IsDir() {
//log.Println("Path: ", path)
dirs.Dirs = append(dirs.Dirs, path)
}
return nil
})
if err != nil {
log.Println(err)
}
log.Println("Continuing Loop")
}
log.Println("Starting Dedup: ")
dirs.Dedup()
log.Println("Post Dedup: ")
for _, dir := range dirs.Dirs {
log.Println(dir)
}
dirs.Watch()
return nil
}

//Dedup ...Remove all duplicate entires from configured directories
func (dirs *WatchDirs) Dedup() {
log.Println("deduping")
uniqueSet := make(map[string]bool, len(dirs.Dirs))
for _, x := range dirs.Dirs {
uniqueSet[x] = true
}
result := make([]string, 0, len(uniqueSet))
for x := range uniqueSet {
result = append(result, x)
}
dirs.Dirs = result
}

//Watch ...Watch the list of created directories for changes
func (dirs *WatchDirs) Watch() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()

done := make(chan bool)
go func() {
for {
select {
case event := <-watcher.Events:
log.Println("event:", event)
if event.Op&fsnotify.Write == fsnotify.Write {
log.Println("modified file:", event.Name)
}
case err := <-watcher.Errors:
log.Println("error:", err)
}
}
}()

for _, dir := range dirs.Dirs {
log.Println("Watching dir: ", dir)
err = watcher.Add(dir)
if err != nil {
log.Println(err)
}
}
<-done
}

编辑:为清晰起见添加了额外的功能。

最佳答案

我不是 100% 确定您的意图。但是对我来说,宏伟的计划似乎是您想要将目录路径附加到一个 slice 中。您想要检查是否添加了新内容,然后将该新目录添加到 slice 中。这是我的简单版本。每隔一秒 由自动收报机定义 我同步路径。我用信号说,“嘿,我想停止监视变化并打印出所有路径”。我还使用一个 channel 来听取来自标准输入的命令来做其他事情(你肯定可以在此基础上构建)。

我无法确切地说出您的原始代码中的故障点在哪里。如果您正在监视更改,那么代码应该是阻塞的,除非您另有说明。

package main

import (
"bufio"
"io"
"log"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
)

type Watcher struct {
Dirs []DirInfo
Ticker *time.Ticker
Stop chan os.Signal
Command chan string
}

type DirInfo struct {
LastMod time.Time
Path string
}

func New() *Watcher {
return &Watcher{
Stop: make(chan os.Signal, 1),
Ticker: time.NewTicker(1 * time.Second),
Command: make(chan string),
}
}

func (w *Watcher) addPath(path string, f os.FileInfo) {
shouldAppend := true
for i, d := range w.Dirs {
if d.Path == path {
w.Dirs[i].LastMod = f.ModTime()
shouldAppend = false
break
}
}
if shouldAppend {
w.Dirs = append(w.Dirs, DirInfo{f.ModTime(), path})
}
}

func (w *Watcher) List() {
if len(w.Dirs) == 0 {
log.Println("Nothing to show")
return
}

for _, d := range w.Dirs {
log.Println(d.Path)
}
return
}

func (w *Watcher) isNew(path string, f os.FileInfo) bool {
for _, d := range w.Dirs {
if path == d.Path {
t := f.ModTime()
return t.After(d.LastMod)
}
}
return true
}

func (w *Watcher) Sync(tops []string) {
for _, top := range tops {
err := filepath.Walk(top, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if f.IsDir() && w.isNew(path, f) {
w.addPath(path, f)
}
return nil
})

if err != nil {
log.Printf("Error %v\n", err)
}
}
}


func main() {
w := New()
tops := []string{}

signal.Notify(w.Stop, syscall.SIGINT, syscall.SIGTERM)

go func() {
s := bufio.NewScanner(os.Stdin)

for {
for s.Scan() {
w.Command <- s.Text()
}
}
}()

for {
select {
case <-w.Ticker.C:
w.Sync(tops)
case <-w.Stop:
log.Println("signalled to stop")
w.List()
os.Exit(0)
case cmd := <-w.Command:
switch cmd {
case "list":
w.List()
}
}
}

}

关于Go filepath.Walk 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45986025/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com