【问题标题】:How to detect Hidden Files in a folder in Go - cross-platform approach如何在 Go 中检测文件夹中的隐藏文件 - 跨平台方法
【发布时间】:2022-01-14 09:41:06
【问题描述】:

我正在通过 golang 中的 filePath.Walk 方法遍历已安装的文件夹,但它也返回隐藏文件。我必须跳过那些隐藏文件。 对于 MaxOS 和 Linux,我们可以通过文件名中的 .prefix 检测隐藏文件,但对于 Windows,当我尝试使用 "syscall" 提供的这种方法 GetFileAttributes 时,它没有检测到这些方法并抛出一个错误。

使用以下方法获取文件

err := filepath.Walk(prefix, func(docPath string, f os.FileInfo, err error) error {

下面是我尝试检测隐藏文件的方法

import (
  "runtime"
  "syscall"
)

func IsHiddenFile(filename string) (bool, error) {

if runtime.GOOS == "windows" {
    pointer, err := syscall.UTF16PtrFromString(filename)
    if err != nil {
        return false, err
    }
    attributes, err := syscall.GetFileAttributes(pointer)
    if err != nil {
        return false, err
    }
    return attributes&syscall.FILE_ATTRIBUTE_HIDDEN != 0, nil
} else {
    // unix/linux file or directory that starts with . is hidden
    if filename[0:1] == "." {
        return true, nil
    }
}
return false, nil

}

错误:

.../ undefined: syscall.UTF16PtrFromString
.../ undefined: syscall.GetFileAttributes
.../ undefined: syscall.FILE_ATTRIBUTE_HIDDEN

我在包名称之前的文件开头添加了这个// +build windows,如下所示:syscall variables undefined,但它仍然无法正常工作并引发相同的错误。

我想知道 go 是否提供了一些常用的方法来检测文件是否隐藏?或者有没有一种方法可以在不接收隐藏文件的情况下获取某个已挂载目录中的所有文件/文件夹?

真的很期待在这里收到一些反馈,谢谢。


编辑:修复了上面提到的问题(请参考下面的 cmets),我也想知道当我们与远程服务器(SMB)连接时,我们如何检测隐藏文件,远程系统可以运行任何操作系统,我们根据运行它的系统编译这些方法。在那种情况下我们如何检测隐藏文件?

【问题讨论】:

    标签: windows go system-calls mount smb


    【解决方案1】:

    条件编译是正确的方法,但它适用于源文件级别,因此您需要两个单独的文件。

    例如:

    hidden_​​notwin.go

    // +build !windows
    
    package main
    
    func IsHiddenFile(filename string) (bool, error) {
        return filename[0:1] == ".", nil
    }
    

    hidden_​​windows.go

    // +build windows
    
    package main
    
    import (
        "syscall"
    )
    
    func IsHiddenFile(filename string) (bool, error) {
        pointer, err := syscall.UTF16PtrFromString(filename)
        if err != nil {
            return false, err
        }
        attributes, err := syscall.GetFileAttributes(pointer)
        if err != nil {
            return false, err
        }
        return attributes&syscall.FILE_ATTRIBUTE_HIDDEN != 0, nil
    }
    

    请注意,上面的 // +build windows 标记是可选的 - _windows 源文件后缀已经具有魔力。更多详情请见How to use conditional compilation with the go build tool

    【讨论】:

    • Go 1.17 引入了//go:build 条件编译指令
    • 是的,我知道,但是 Go 1.16 仍然被广泛使用,它需要+build。明年更新;)
    • 我错过了_windows 部分,在点击此链接后通过实验找到了它:freshman.tech/snippets/go/detect-hidden-file 非常感谢您的回复。
    • @rustyx 你能告诉我当我们连接到远程服务器时如何检测隐藏文件,远程系统可以运行任何操作系统,我们根据它的系统编译这些方法继续运行。在那种情况下我们如何检测隐藏文件?
    • 这已经是另一个问题了,它取决于所使用的协议、源和目标操作系统。 SMB 可以保留文件属性,但其他人不能。
    猜你喜欢
    • 2010-09-21
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 2017-08-11
    • 2018-10-07
    • 1970-01-01
    相关资源
    最近更新 更多