Creating a file in a directory

6,685 views
Skip to first unread message

Scott Turnbull

unread,
May 29, 2013, 2:49:00 PM5/29/13
to golan...@googlegroups.com
I'm trying to take a filepath string and create a Method on a type that stores it to parse the string, create the relevant directories if needed and create the file.  I seem to be able to create the directory as I might expect but I get an error when trying to create the file.  How do you create a file in a directory in Go?  I'm very new to all of this and the NewFile fd property seems like it might be what I need but the uintptr is escaping me right now.

I'm pasting the method I'm having trouble with below.  Thank you for any insight.

// Writes key value pairs to a tag file.
func (tf *TagFile) Create() {
    // Create directory if needed.
    basepath := path.Dir(tf.Filepath)
    filename := path.Base(tf.Filepath)
    if os.MkdirAll(basepath, 0666) != nil {
        panic("Unable to create directory for tagfile!")
    }

    // Create the tagfile.
    fileOut, err := os.Create(strings.Join([]string{basepath, filename}, "/"))
    if err != nil {
        panic("Unable to create tag file!")
    }
    defer fileOut.Close()

    // Write fields and data to the file.
    for key, data := range tf.Data {
        _, err := io.WriteString(fileOut, fmt.Sprintln(formatField(key, data)))
        if err != nil {
            panic("Unable to write data to tagfile.")
        }
    }
}

minux

unread,
May 29, 2013, 2:58:04 PM5/29/13
to Scott Turnbull, golan...@googlegroups.com
On Thu, May 30, 2013 at 2:49 AM, Scott Turnbull <stream...@gmail.com> wrote:
I'm trying to take a filepath string and create a Method on a type that stores it to parse the string, create the relevant directories if needed and create the file.  I seem to be able to create the directory as I might expect but I get an error when trying to create the file.  How do you create a file in a directory in Go?  I'm very new to all of this and the NewFile fd property seems like it might be what I need but the uintptr is escaping me right now.

I'm pasting the method I'm having trouble with below.  Thank you for any insight.

// Writes key value pairs to a tag file.
func (tf *TagFile) Create() {
    // Create directory if needed.
    basepath := path.Dir(tf.Filepath)
    filename := path.Base(tf.Filepath)
    if os.MkdirAll(basepath, 0666) != nil {
you should change 0666 to 0777. or you won't be able to create
files in a dir with perm 0666.
        panic("Unable to create directory for tagfile!")
    }

    // Create the tagfile.
    fileOut, err := os.Create(strings.Join([]string{basepath, filename}, "/"))
you'd better use path/filepath.Join for this. 
    if err != nil {
        panic("Unable to create tag file!")
    }
    defer fileOut.Close()

    // Write fields and data to the file.
    for key, data := range tf.Data {
        _, err := io.WriteString(fileOut, fmt.Sprintln(formatField(key, data)))
why not use fmt.Fprintln directly? 

Scott Turnbull

unread,
May 29, 2013, 4:03:02 PM5/29/13
to golan...@googlegroups.com, Scott Turnbull
Thanks for your suggestions, they definitely helped simplify the code.

I'm still getting an error though when I try to create the file.  I created this snippet in hopes that it's more helpful.  As I said I'm new to Go and I'm sure I'm overlooking something simple and thanks for any help.

andrey mirtchovski

unread,
May 29, 2013, 4:05:37 PM5/29/13
to Scott Turnbull, golang-nuts
it would help if you share what the error was. your code works for me as is.

Scott Turnbull

unread,
May 29, 2013, 4:14:18 PM5/29/13
to golan...@googlegroups.com, Scott Turnbull
Alright I think I have this fixed but I'm not sure I understand it.  using 0777 directly for the FileMode does not result in the permission I would expect.  using os.ModePerm does however and using that I can write the file just fine.


On Wednesday, May 29, 2013 2:58:04 PM UTC-4, minux wrote:

minux

unread,
May 29, 2013, 4:16:01 PM5/29/13
to Scott Turnbull, golan...@googlegroups.com
On Thu, May 30, 2013 at 4:03 AM, Scott Turnbull <stream...@gmail.com> wrote:
Thanks for your suggestions, they definitely helped simplify the code.

I'm still getting an error though when I try to create the file.  I created this snippet in hopes that it's more helpful.  As I said I'm new to Go and I'm sure I'm overlooking something simple and thanks for any help.

Can't spot anything obviously wrong. Please provide more details on
the error (for example, what does your program output?)

it makes sense to manually try to do the work the program tries to do
and see if it could succeed.
for example, if your program successfully makes a directory called /foo/bar,
and then fails to create /foo/bar/somefile, you should try to create that file
in the path manually to see if it works.

ps: i suggest you include some contextual information in panics (or better,
return an error in Create() method), so that when error occurs, you know
exactly what's happening.

minux

unread,
May 29, 2013, 4:18:58 PM5/29/13
to Scott Turnbull, golan...@googlegroups.com
On Thu, May 30, 2013 at 4:14 AM, Scott Turnbull <stream...@gmail.com> wrote:
Alright I think I have this fixed but I'm not sure I understand it.  using 0777 directly for the FileMode does not result in the permission I would expect.  using os.ModePerm does however and using that I can write the file just fine.
the actual permission is still subject to your umask setting. 

what do you mean by "using os.ModePerm does"?
could you please show what changes made the program working correctly?

using 0777 for os.MkdirAll normally should work just ok (except when you're
concerned about others reading your directories, but at least you need rwx
perm. for the owner if you want to use the directory normally).

Scott Turnbull

unread,
May 29, 2013, 5:06:40 PM5/29/13
to minux, golan...@googlegroups.com
I am obviously tangled up somewhere. I tried setting the code back to what I believe was giving me the error but it no longer does and works as I would expect.  There must have been some other error I overlooked and fixed.  Thanks for your feedback and for my confusion.

Carlos Castillo

unread,
May 30, 2013, 8:11:29 AM5/30/13
to golan...@googlegroups.com, minux
One suggestion, even if you decide to keep your panic-oriented error handling strategy, you should still include the error in the panic, so you can see what the error claims is wrong, instead of just what you assume is wrong.

For example, your os.MkdirAll section:

if os.MkdirAll(basepath, 0666) != nil {
        panic("Unable to create directory for tagfile!")
}

Would be more useful (to debug) as:

if err := os.MkdirAll(basepath, 0666); err != nil {
        panic("Unable to create directory for tagfile! - " + err.Error())
}

As it includes the error's message (how MkdirAll failed) in addition to what you were trying to do at the time.
Reply all
Reply to author
Forward
0 new messages