Skip to content

Instantly share code, notes, and snippets.

@mattes
Last active June 6, 2026 21:11
Show Gist options
  • Select an option

  • Save mattes/d13e273314c3b3ade33f to your computer and use it in GitHub Desktop.

Select an option

Save mattes/d13e273314c3b3ade33f to your computer and use it in GitHub Desktop.
Check if file or directory exists in Golang
if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) {
// path/to/whatever does not exist
}
if _, err := os.Stat("/path/to/whatever"); !os.IsNotExist(err) {
// path/to/whatever exists
}
@msvitok77

Copy link
Copy Markdown

The condition for checking if the folder / file exist is not exactly correct. os.Stat might fail because of permissions, etc, but the file may still exists. So it should be !os.IsNotExist(err). Using err == nil in that case gives wrong result as the file doesn't exist.

@shinriyo

Copy link
Copy Markdown

fmt.Printf("Error: %s", err)

@cuixin

cuixin commented Nov 17, 2017

Copy link
Copy Markdown

@yshadow, absolutely right!

@kshitij10496

Copy link
Copy Markdown

@sunicy

sunicy commented Jan 2, 2018

Copy link
Copy Markdown

One more thing, os.IsExist() would be blind to EMPTY FILE. Please always consider IsNotExist() instead.

Here is the official implementation of both of the function.

func isExist(err error) bool {
	err = underlyingError(err)
	return err == syscall.EEXIST || err == syscall.ENOTEMPTY || err == ErrExist
}

func isNotExist(err error) bool {
	err = underlyingError(err)
	return err == syscall.ENOENT || err == ErrNotExist
}

@JitinGuglani

Copy link
Copy Markdown

Hi all,
very funny behavior of os.stat(). I have written the below code and os.stat() is behaving very wierd.
I am using windows and go lang version : go1.10.1 windows/amd64.
Pls help.

package main

import "os"

func main() {

directoryName := getName()
_, err := os.Stat(directoryName)
if err != nil {
	println("os.Stat(): error for folder name ",directoryName)
	println("and error is : ", err.Error())
	if os.IsNotExist(err ) {
		println("Directory Does not exists.")
	}
} else {
	println("os.Stat(): No Error for folderName : ", directoryName)
}

}
// none of these folder exists on my computer so ideally all the returns statements should give error, but only some are giving.
func getName() string {
//no error if I return the "d:\invalidFolder" value
//return "d:\invalidFolder"
//error if I return the "d:\InvalidFolderName" value
//return "d:\InvalidFolderName"
// error if I return the "d:\xyz\this\folder" value
//return "d:\xyz\this\folder"
// no error if I return the "d:\xyz" value
//return "d:\xyz"
// error, if I return the "d:\doesitgiveError" value
//return "d:\doesitgiveError"
// error if I return "d:\abc" value
return "d:\abc"
}

@SteelCrow

Copy link
Copy Markdown

Backslash \ is escape character, that's why I think you getting this strange behaviour.

@daqing613

Copy link
Copy Markdown

Thanks.

@ilyaiqoqo

Copy link
Copy Markdown

like!

@danawoodman

Copy link
Copy Markdown

Why not use os.IsExist instead of !os.IsNotExist?

@mattes

mattes commented Oct 21, 2019

Copy link
Copy Markdown
Author

Here is an example to explain the difference, why os.IsExist != !os.IsNotExist:

if _, err := os.Stat("/path/to/whatever"); os.IsExist(err) {
	// never triggers, because err is nil if file actually exists
}
if err := os.Mkdir("/path/to/whatever", 0755); os.IsExist(err) {
	// triggers if dir already exists
}

@digglife

digglife commented Apr 13, 2020

Copy link
Copy Markdown

Is this normal? Have anyone here ever typed this long to just test if a file/dir exists in any other modern language?

Thanks for the solution tho.

@rickyzhang82

Copy link
Copy Markdown

@digglife Welcome to this duck up Golang world.

@kfelter

kfelter commented Aug 18, 2020

Copy link
Copy Markdown

👍

@ravindrabhargava

Copy link
Copy Markdown

what about if need to check for "*.txt" in Linux dir if the file exists or not, I tried *.txt but it's not working at all

if _, err := os.Stat("*.txt"); err == nil {
fmt.Printf("File exists\n");
} else {
fmt.Printf("File does not exist\n");
}

@mattes

mattes commented Sep 21, 2020

Copy link
Copy Markdown
Author

@pavelerokhin

Copy link
Copy Markdown

super!

@KEINOS

KEINOS commented Mar 21, 2021

Copy link
Copy Markdown

Great! It was so helpful! 👍

@ondrejsika

Copy link
Copy Markdown

Thanks 👍

@gowizzard

Copy link
Copy Markdown

Thanks

@9cat

9cat commented Apr 27, 2022

Copy link
Copy Markdown

that helps~

@yangyongzhi7

Copy link
Copy Markdown

Thanks

@lukemilby

Copy link
Copy Markdown

I was here.

Thanks

@magicwarms

Copy link
Copy Markdown

Thanks!

@BloodmageThalnos

Copy link
Copy Markdown

shanks!

@stricklandye

Copy link
Copy Markdown

haha, although it is trivial still helps a lot ,thanks!

@mayooot

mayooot commented Feb 19, 2024

Copy link
Copy Markdown

Thanks

@lazypwny751

Copy link
Copy Markdown

thanks 👍

@Anhdao153

Copy link
Copy Markdown

thanks

@LassePladsen

LassePladsen commented Jun 6, 2026

Copy link
Copy Markdown

NB: as the docs say, you should rather now use errors.Is(err, fs.ErrNotExist) instead of os.IsNotExist(err):

This function predates errors.Is. It only supports errors returned by the os package. New code should use errors.Is(err, fs.ErrNotExist).

https://pkg.go.dev/os#IsNotExist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment