用Go编写的目录walker停止使用正在使用的文件(已锁定)错误

时间:2017-03-30 20:50:35

标签: windows file go directory

我有这个目录漫步者:

package main

import (
    "fmt"
    "os"
    "path/filepath"
    "strings"
)

var exts = [...]string{"*.psd", "*.cdr", "*.tiff", "*.svg", "*.png", "*.jpeg", "*.jpg", "*.pdf", "*.txt", "*.rtf", "*.docx", "*.doc", "*.xlsx", "*.xls", "*.ppt", "*.pptx", "*.accdb", "*.csv", "*.dwg", "*.dxf", "*.dng", "*.arw", "*.srf", "*.sr2", "*.bay", "*.crw", "*.cr2", "*.dcr", "*.kdc", "*.erf", "*.mef", "*.mrw", "*.nef", "*.nrw", "*.orf", "*.raf", "*.raw", "*.rwl", "*.rw2", "*.r3d", "*.ptx", "*.pef", "*.srw"}
var skipdir = [...]string{"WINDOWS", "Program Files"}

func VisitFile(fp string, fi os.FileInfo, err error) error {
    proceed := true
    if err != nil {
        fmt.Println(err) // can't walk here,
        return nil       // but continue walking elsewhere
    }
    if fi.IsDir() {
        return nil // not a file.  ignore.
    }
    for _, value := range skipdir {
        if strings.Contains(filepath.Dir(fp), value) {
            proceed = false
            break
        }
    }
    if proceed == true {
        for _, value := range exts {
            matched, err := filepath.Match(value, fi.Name())
            if err != nil {
                fmt.Println(err) // malformed pattern
                return err       // this is fatal.
            }
            if matched {
                fmt.Println(fp)
            }
        }
    } else {
        //fmt.Println(proceed)
        return nil
    }
    return nil
}

func getdrives() (r []string) {
    for _, drive := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" {
        _, err := os.Open(string(drive) + ":\\")
        if err == nil {
            r = append(r, string(drive))
        }
    }
    return
}

func main() {
    drives := getdrives()
    for _, value := range drives {
        filepath.Walk(value+":/", VisitFile)
    }
}

然而,当它到达pagefile.sys时,我收到此消息:

  

GetFileAttributesEx C:\ pagefile.sys:进程无法访问该文件,因为       它被另一个进程使用。

因为文件正在使用,程序停止。如何禁止此消息继续行走?

1 个答案:

答案 0 :(得分:1)

如果您希望步行完成,则不应在函数内返回错误。您应该在切片内收集错误。 将您的功能更改为:

// Put this var outside your function
var myErrors []error
func VisitFile(fp string, fi os.FileInfo, err error) []error {

只需将变量作为错误片段。然后更改return err

   if proceed == true {
        for _, value := range exts {
            matched, err := filepath.Match(value, fi.Name())
            if err != nil {
                fmt.Println(err) // malformed pattern
                // collect the error
                myErrors = append(myErrors,err)
                // you could jump out of this by 
                return nil
            }
            if matched {
                fmt.Println(fp)
            }
        }
    }

最后,您可以查看myErrors切片。