Search code examples
filegopathdirectoryfile-exists

How to check file `name` (with any extension) does exist in the directory in Golang?


I know I could check the file does exist or not in Golang by the answers of the following questions.

The code looks like this.

_, err := os.Stat(path)
if err == nil {
    log.Printf("File %s exists.", path)
} else if os.IsNotExist(err) {
    log.Printf("File %s not exists.", path)
} else {
    log.Printf("File %s stat error: %v", path, err)
}

But here's my real question, how do I check the filename does exist (has been used) in the specified directory? For example if I have a file tree like this:

--- uploads
       |- foo.png
       |- bar.mp4

I wanted to check if there's any file is using the specified name..

used := filenameUsed("uploads/foo")
fmt.Println(used) // Output: true

used = filenameUsed("uploads/hello")
fmt.Println(used) // Output: false

How do I implement the filenameUsed function?

Google gave me a path/filepath package as the result but I have no clue about how to use it.


Solution

  • You may use the filepath.Glob() function where you can specify a pattern to list files.

    The pattern to be used is basically the name you wish to check if used, extended with the any extension pattern.

    Example:

    func filenameUsed(name string) (bool, error) {
        matches, err := filepath.Glob(name + ".*")
        if err != nil {
            return false, err
        }
        return len(matches) > 0, nil
    }
    

    Using / testing it:

    fmt.Print("Filename foo used: ")
    fmt.Println(filenameUsed("uploads/foo"))
    fmt.Print("Filename bar used: ")
    fmt.Println(filenameUsed("uploads/bar"))
    

    Example output:

    Filename foo used: true <nil>
    Filename bar used: false <nil>
    

    However, note that filenameUsed() returning false (and nil error) does not mean a file with that name won't exist if you attempt to create one after. Meaning checking it and attempting to create such a file does not guarantee atomicity. If your purpose is to create a file if the name is not used, then simply try to create the file in the proper mode (do not overwrite if exists), and handle the (creation) error returned by that call.