Check if file exists

5,057 views
Skip to first unread message

Nathan Trimble

unread,
Oct 18, 2011, 12:50:18 AM10/18/11
to golan...@googlegroups.com
Hopefully I'm not missing the obvious here, but I don't see a function anywhere to check if a file exists.  The code below just executes the second print statement, so I cannot detect if the error is due to the file's non-existence or some other error.

I must not be using os.ENOENT correctly...  Suggestions?  Thanks for the continued help.  This has been fun, and I'm getting closer to a working rewrite of our in-house program.

package main

import (
"os"
"fmt"
)

func main() {
path := "/does/not/exist"
file, err := os.Open(path)
defer file.Close()
if err == os.ENOENT {
fmt.Printf("%s not found\n", path)
} else if err != nil {
fmt.Printf("%s, %v\n", path, err)
}
}

Jan Mercl

unread,
Oct 18, 2011, 1:15:11 AM10/18/11
to golan...@googlegroups.com
On Tuesday, October 18, 2011 6:50:18 AM UTC+2, Nate Trimble wrote:
Hopefully I'm not missing the obvious here, but I don't see a function anywhere to check if a file exists.  

Nathan Trimble

unread,
Oct 18, 2011, 1:33:59 AM10/18/11
to golan...@googlegroups.com
In so far as I can tell, os.Stat does me no good for a file that does not exist:

path := "/does/not/exist"
fi, err := os.Stat(path)
if fi == nil && err != nil {
fmt.Printf("%v\n", err)  //"stat /does/not/exist: no such file or directory"
}

So is fi nil because it doesn't exist, or some other reason?  I can't tell.  The error message tells me it doesn't exist, so am I to parse the error output to detect if that is the case?  There's got to be a better way.  If not, why does the documentation mention os.ENOENT?  Thanks.

Jan Mercl

unread,
Oct 18, 2011, 3:01:12 AM10/18/11
to golan...@googlegroups.com
On Tuesday, October 18, 2011 7:33:59 AM UTC+2, Nate Trimble wrote:
In so far as I can tell, os.Stat does me no good for a file that does not exist:

path := "/does/not/exist"
fi, err := os.Stat(path)
if fi == nil && err != nil {
fmt.Printf("%v\n", err)  //"stat /does/not/exist: no such file or directory"
}

So is fi nil because it doesn't exist, or some other reason?  I can't tell.  The error message tells me it doesn't exist, so am I to parse the error output to detect if that is the case?  There's got to be a better way.  If not, why does the documentation mention os.ENOENT?  Thanks.

package main

import (
        "fmt"
        "os"
)

func main() {
        _, err := os.Stat("/no/such/file")
        if err != nil {
                if e, ok := err.(*os.PathError); ok && (e.Error == os.ENOENT || e.Error == os.ENOTDIR) {
                        fmt.Println("no such file or directory")
                        return
                }

                fmt.Println(err)
                return
        }

        fmt.Println("exists")
}
 

Erik Unger

unread,
Oct 18, 2011, 5:05:31 AM10/18/11
to golang-nuts
I am all for orthogonal APIs but an operation that is so common and
frequently used like checking for existence of a file/directory should
get its own function!

-Erik

Jan Mercl

unread,
Oct 18, 2011, 5:16:16 AM10/18/11
to golan...@googlegroups.com
Actually I wouldn't recommend such checking for file existence at all - AFAICS it's racy and thus not really reliable/usable. Just open the file and check the err as in the previous example.

Russ Cox

unread,
Oct 18, 2011, 8:32:09 AM10/18/11
to Nathan Trimble, golan...@googlegroups.com
Can you say a little bit more about what you are trying to do?

> if err == os.ENOENT {
> fmt.Printf("%s not found\n", path)
> } else if err != nil {
> fmt.Printf("%s, %v\n", path, err)
> }

This in particular boils down to
fmt.Printf("%s\n", err)
In either case it will already say the name and what went wrong.

Usually it is better to try the operation you care about and
let the OS tell you whether it worked, instead of trying to predict
whether it will work beforehand.

Russ

Nathan Trimble

unread,
Oct 18, 2011, 11:02:41 AM10/18/11
to r...@golang.org, golan...@googlegroups.com
In my case I want to have different behavior if say the file does not exist than if the file simply cannot be opened for whatever reason.  A file that doesn't exist will (at a later time) get created, whereas a different kind of error will get logged.  I see now there are ways around it (like creating the file immediately), I just expected a file exists function to be available somewhere.

Archos

unread,
Oct 18, 2011, 1:01:48 PM10/18/11
to golang-nuts

Nathan Trimble

unread,
Oct 18, 2011, 1:21:56 PM10/18/11
to Archos, golang-nuts
Oh interesting.  Excuse the ignorance please, but could someone explain the line below to me?

e, ok := err.(*os.PathError);

err is an os.Error type correct? So what is "err.(*os.PathError)" doing?  I've been looking at the language spec and os.Error type, but it's not coming to me.

chris dollin

unread,
Oct 18, 2011, 1:27:56 PM10/18/11
to Nathan Trimble, Archos, golang-nuts
On 18 October 2011 18:21, Nathan Trimble <nathan....@gmail.com> wrote:
> Oh interesting.  Excuse the ignorance please, but could someone explain the
> line below to me?
>
> e, ok := err.(*os.PathError);
>
> err is an os.Error type correct? So what is "err.(*os.PathError)" doing?

It's a type assertion. If err is of actual type *os.PathError, assign the
value to (a probably freshly declared) e (which will/should have type
*os.PathError) and true to ok; otherwise assign false to ok and
a zero value to e.

Note that os.Error is an interface type.

Chris

--
Chris "allusive" Dollin

Nathan Trimble

unread,
Oct 18, 2011, 1:31:09 PM10/18/11
to chris dollin, Archos, golang-nuts
Aha, makes perfect sense.  Thanks to all for your help.

-Nate

Brad Fitzpatrick

unread,
Oct 18, 2011, 2:39:24 PM10/18/11
to Nathan Trimble, golan...@googlegroups.com
This confused me too when I first came to Go.

I filed http://code.google.com/p/go/issues/detail?id=2383 to flesh out the docs a bit.

Hraban Luyat

unread,
Jan 13, 2013, 8:15:30 PM1/13/13
to golan...@googlegroups.com, Nathan Trimble, Archos, ehog....@googlemail.com
Old thread, but this might be of interest for some late-to-the-party-Googlers: be advised of the os.IsNotExist function.


Greetings,

Hraban
Reply all
Reply to author
Forward
0 new messages