-
-
Save RyotaBannai/ac3de36689cb5ca4ef93c68dabc33eda to your computer and use it in GitHub Desktop.
os.IsExist(err) vs os.IsNotExist(err)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Watch out, os.IsExist(err) != !os.IsNotExist(err) | |
They are error checkers, so use them only when err != nil, and you want to handle | |
specific errors in a different way! | |
Their main purpose is to wrap around OS error messages for you, so you don't have to test | |
for Windows/Unix/Mobile/other OS error messages for "file exists/directory exists" and | |
"file does not exist/directory does not exist" | |
This way you can handle such an error, while still failing on other unexpected errors like "permission denied", | |
"filesystem error", "wrong filename" error, etc. | |
*/ | |
// We want to create a symlink, but the target path exists already : | |
if _, err := os.Symlink("/old/path", "/path/to/whatever"); os.IsExist(err) { | |
// error happened, can't Symlink | |
// can't create symlink because /path/to/whatever already exists | |
} | |
// We want to stat a file, but it doesn't exist : | |
if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) { | |
// error happened, can't Stat! | |
// /path/to/whatever does not exist | |
} | |
// BUT : | |
// Anti-pattern : We want to stat a file, and continue if it exists : | |
if _, err := os.Stat("/file/that/exists"); os.IsExist(err) { | |
// will never trigger! | |
// why? because os.Stat runs normally if file exists. | |
// it's expected behaviour for os.Stat, so it doesn't throw an error | |
// os.IsExist() does not receive an error ( it's nil ), so it can't tell you | |
// if the error message was "file not found" | |
} | |
// Instead : | |
// We want to stat a file, and continue if it exists : | |
_, err := os.Stat("/file/that/exists"); | |
if err != nil { | |
if os.IsNotExist(err) { | |
// file does not exist, do something | |
} else { | |
// more serious errors | |
} | |
} | |
// file exists.. continue with code here, or in else statement, or specify if err == nil { // do something } | |
/* | |
os.IsExist(err) is good for cases when you expect the file to not exist yet, | |
but the file actually exists : | |
*/ | |
os.Symlink("/path/that/exists", "/path/to/symlink/target") | |
// os.IsExist(err) will trigger when target exists already | |
os.Mkdir(target) | |
// os.IsExist(err) will trigger because target path already exists | |
os.OpenFile(target, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) | |
// os.IsExist(err) will trigger when target exists because O_EXCL means that file should not exist yet | |
/* | |
os.IsNotExist(err) is good for more common cases where you expect the file to exists, | |
but it actually doesn't exist : | |
*/ | |
os.Chdir() | |
os.Stat() | |
os.Open() | |
os.OpenFile() // without os.O_EXCL | |
os.Chmod() | |
os.Chown() | |
os.Close() | |
os.Read() | |
os.ReadAt() | |
os.ReadDir() | |
os.Readdirnames() | |
os.Seek() | |
os.Truncate() | |
os.Write() | |
os.WriteAt() | |
os.WriteString() | |
// etc... | |
// More reading : | |
// http://stackoverflow.com/a/12518877 | |
// http://stackoverflow.com/questions/25939584/file-both-exists-and-not-exists-in-go/25939743#25939743 | |
// | |
// https://github.com/golang/go/search?utf8=%E2%9C%93&q=IsExist | |
// https://golang.org/pkg/os/#IsExist | |
// | |
// http://stackoverflow.com/search?q=os.IsExist | |
// http://stackoverflow.com/search?q=os.IsNotExist |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment