Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.5k views
in Technique[技术] by (71.8m points)

go 判断文件的问题

写了一个文件遍历的,发现死循环。 排查问题发现是 s.IsDir() 问题

if s, err := os.Stat(path); err==nil{
 // 抛出错误
}else{
    return s.IsDir()
}

go 只提供了一个 s.IsDir() 。 但其实是系统除了目录和文件(侠义上的文件还有 socket文件,链接文件,回收站,块设备等等

然后我从系统更目录扫描,出现

...... 无数相同输出
###  $Recycle.Bin
文件夹 $Recycle.Bin
文件夹 $Recycle.BinS-1-5-18
###  $Recycle.Bin
文件夹 $Recycle.Bin
文件夹 $Recycle.BinS-1-5-18
###  $Recycle.Bin
文件夹 $Recycle.Bin
文件夹 $Recycle.BinS-1-5-18
###  $Recycle.Bin
文件夹 $Recycle.Bin
文件夹 $Recycle.BinS-1-5-18
###  $Recycle.Bin
FAIL    Cherry/Core/Choreser    3.454s
...... 无数相同输出

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

os 包里 FileInfoFileMode里不是有这块的处理么
看下FileMode里的定义

const (
    // The single letters are the abbreviations
    // used by the String method's formatting.
    ModeDir        FileMode = 1 << (32 - 1 - iota) // d: is a directory
    ModeAppend                                     // a: append-only
    ModeExclusive                                  // l: exclusive use
    ModeTemporary                                  // T: temporary file; Plan 9 only
    ModeSymlink                                    // L: symbolic link
    ModeDevice                                     // D: device file
    ModeNamedPipe                                  // p: named pipe (FIFO)
    ModeSocket                                     // S: Unix domain socket
    ModeSetuid                                     // u: setuid
    ModeSetgid                                     // g: setgid
    ModeCharDevice                                 // c: Unix character device, when ModeDevice is set
    ModeSticky                                     // t: sticky
    ModeIrregular                                  // ?: non-regular file; nothing else is known about this file

    // Mask for the type bits. For regular files, none will be set.
    ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular

    ModePerm FileMode = 0777 // Unix permission bits
)

os.Statos.Lstat 两个函数用来获取文件类型,但是os.Stat具有穿透连接能力,如果你去获取一个软链的 FileInfo,他会返回软链到的文件的信息,你既然想知道他的具体类型,就要使用 os.Lstat

回到你上面的代码.err==nil是抛出错误?然后再去判断是不是目录? 这块的逻辑是不是有问题,你看下官方的示例吧.

package main

import (
    "fmt"
    "log"
    "os"
)

func main() {
    fi, err := os.Lstat("some-filename")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("permissions: %#o
", fi.Mode().Perm()) // 0400, 0777, etc.
    switch mode := fi.Mode(); {
    case mode.IsRegular():
        fmt.Println("regular file")
    case mode.IsDir():
        fmt.Println("directory")
    case mode&os.ModeSymlink != 0:
        fmt.Println("symbolic link")
    case mode&os.ModeNamedPipe != 0:
        fmt.Println("named pipe")
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...