Home > Net >  How to detect Hidden Files in a folder in Go - cross-platform approach
How to detect Hidden Files in a folder in Go - cross-platform approach

Time:12-10

I'm iterating through a mounted folder via filePath.Walk method in golang, but it returns the hidden files as well. I have to skip those hidden files. For MaxOS and Linux, we can detect hidden file via .prefix in the filename, but for windows, when I'm trying to us this method GetFileAttributes, provided by "syscall", it's not detecting these methods and throwing an error.

Using below method to fetch the file

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

Below is how I'm trying to detect the hidden files

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

}

Error :

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

I added this // build windows in the start of the file before package name as suggested here : syscall variables undefined but it's sill not working and throwing the same error.

I need to know if go provides some common method to detect if a file is hidden or not? Or is there a way I can fetch all the files/folder in some mounted directory without receiving hidden files in the first place?

Really looking forward on receiving some feedback here, thanks.

CodePudding user response:

Conditional compilation is the right way to go, but it applies at source file level, so you need two separate files.

For example:

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
}

Note that // build windows tag above is optional - the _windows source file suffix does the magic already. For more details see How to use conditional compilation with the go build tool.

  • Related