2016-09-19 2 views
2

Ich muss ein Dateisystem in Golang laufen und muss in der Lage sein, den Scanvorgang nach dem Neustart fortzusetzen.Wie benutze ich seekdir/telldir in Golang?

In C kann ich dies über telldir() und dann eine seekdir() während der Fortsetzung tun.

Golang bietet nur eine filepath.Walk()-Funktion, aber das bietet keine Möglichkeit, das Dateisystem von einem bestimmten Pfad oder Punkt zu starten.

Dies macht es ineffizient für große Dateisysteme

Jede Art und Weise um ihn herum?

Antwort

2

Die Signatur für filepath.walk ist:

func Walk(root string, walkFn WalkFunc) error 

Die Dokumentation besagt, dass es in dem Verzeichnis von root und der Unterzeichnung der Callback-Funktion (walkFn) ist angegeben beginnt:

type WalkFunc func(path string, info os.FileInfo, err error) error 

So Sie kann den Scan in einem beliebigen Verzeichnis starten und das Dateisystem damit als Root durchlaufen. Sie können nicht mitten durch ein Verzeichnis starten, aber Sie können den Baum, den Sie gerade gehen, selektiv beschneiden.

Es gibt auch einen "magischen" Rückgabewert, filepath.SkipDir, der entweder ein Verzeichnis (wenn zurückgegeben wird, wenn der Rückruf in einem Verzeichnis aufgerufen wird) oder die restlichen Dateien im Verzeichnis (wenn der Rückruf auf a Datei).

Dies kann genug sein, um das Verhalten, das Sie wollen, zu bekommen, aber es ist ein wenig schwer aus Ihrer Frage zu sagen. Sie können nicht aus einem filepath.Walk Aufruf ausbrechen und dann später fortsetzen. Allerdings können Sie diese Einschränkung möglicherweise umgehen, indem Sie Gstagloins innerhalb Ihres Rückrufs erstellen, wenn Sie hauptsächlich damit zu tun haben, dass der Rückruf einige Zeit in Anspruch nimmt.

0

Sie können Ihre eigene Zustandsmaschine schreiben:
1- Gehen Sie den ganzen Weg mit filepath.Walk() und Puffer das Ergebnis, dann verwenden Sie diesen Puffer mit Zustand (schnell).

2- Speichern Sie die root string für den angehaltenen Zustand, dann scannen Sie von Grund auf, bis Sie den gespeicherten Pfad (langsam) erreichen.

3- Sie Kanäle verwenden können, wie diese Arbeitsprobe:
(anprobieren The Go Playground):

package main 

import (
    "fmt" 
    "os" 
    "path/filepath" 
    "sync" 
    "time" 
) 

var dirs = make(chan string, 10) 
var wg sync.WaitGroup 

func main() { 
    wg.Add(1) 
    go GetDirectories(`../`, `*`) 
    fmt.Println() 

    fmt.Println(<-dirs) 
    fmt.Println(<-dirs) 

    fmt.Println() 
    time.Sleep(1 * time.Second) // pause 

    for dir := range dirs { 
     fmt.Println(dir) 
    } 
    wg.Wait() 
    fmt.Println(`Done.`) 
} 

// Returns the names of the subdirectories (including their paths) 
// that match the specified search pattern in the specified directory. 
func GetDirectories(root, pattern string) { 
    defer wg.Done() 
    defer close(dirs) 
    filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { 
     if !fi.IsDir() { 
      return nil 
     } 
     matched, err := filepath.Match(pattern, fi.Name()) 
     if err != nil { 
      return err 
     } 
     if !matched { 
      return nil 
     } 
     dirs <- path //dirs = append(dirs, path) 
     return nil 
    }) 
}