Create a File, Append to it

4,354 views
Skip to first unread message

Francisco Diaz Trepat - gmail

unread,
Nov 10, 2010, 1:12:58 PM11/10/10
to golang-nuts
Hi guys, I want to create a file, but I don't understand the fd parameter about the file descriptor.

I also want to append to the newly created file.

I found this code in the list:


package main

import ("fmt";"io";"io/ioutil";"os")

const file = "temp.txt"

func write(flag int, text string) {
       f, err:=os.Open(file, flag, 0666)
       if err != nil { fmt.Println(err); return }
       n, err := io.WriteString(f, text)
       if err != nil { fmt.Println(n, err); return }
       f.Close()
       data, err := ioutil.ReadFile(file)
       if err != nil { fmt.Println(err); return }
       fmt.Println(string(data))
}

func main() {
       write(os.O_CREAT|os.O_TRUNC|os.O_RDWR, "new")
       for i := 0; i < 2; i++ {
               write(os.O_APPEND|os.O_RDWR, "|append")
       }
}

Will that create the file also? (Only ask because I see the os.O_CREAT and imagine that that primitive will create the file if not present) </imagination>

f(t)

Steven

unread,
Nov 10, 2010, 1:23:33 PM11/10/10
to Francisco Diaz Trepat - gmail, golang-nuts
On Wednesday, November 10, 2010, Francisco Diaz Trepat - gmail

os.Creat will cause the file to be created if it does not already
exist. Have you tried looking at the package doc? It tells you this.

http://golang.org/pkg/os/

André Moraes

unread,
Nov 10, 2010, 1:25:22 PM11/10/10
to golang-nuts
The "fd" is usefull when you have a open file and want to share that file with another object/function/goroutine.

For the simple use:

open a file
write... write... write (or read... read... read)
close the file

The fd isn't really used.

Francisco Diaz Trepat - gmail

unread,
Nov 10, 2010, 1:46:25 PM11/10/10
to André Moraes, golang-nuts
Thanks Andre, I also already found another mail on the list in which it mentions that os.Open with O_CREAT creates de file if not present.

Perfect for me.

Do you know if there is an interface that has only the String() method or something like that

Because I have a two package/subdirectory project

importer
importer/utils

in importer/utils I have put the Contents function from the EffectiveGo to read all file and return a string.

Now I wish to dump a map of some structures that I have in the importer package, and would like to have the dump function in the utils package. So AFAIK I have two options:

Either I move the structs to the importer/util package, and write a function to accept the maps of my structures, or I have an interface in my utils package and have the defacto implementation.

By this I also include the use of interfaces in this small program to show Go@work

f(t)

2010/11/10 André Moraes <and...@gmail.com>

André Moraes

unread,
Nov 10, 2010, 1:54:35 PM11/10/10
to golang-nuts
//=== importer
type DumpString interface {
  Dump(data string)
}

//=== importer/utils

func DumpTextFile(string fileName, ds DumpString) {
  for {
    var line string
    //read the line
    ds.Dump(line)
  }
}

2010/11/10 Francisco Diaz Trepat - gmail <francisco....@gmail.com>

Francisco Diaz Trepat - gmail

unread,
Nov 10, 2010, 2:06:48 PM11/10/10
to André Moraes, golang-nuts
Can I do it like this:

//=== importer
type Staff interface {
    name    string
    blah    string
    String()
}

func (staff *Staff) String() string {
   return name + ":" + blah
}

staff := map[string] *Staff{"a":&Staff{name: "Andre", blah: "blah"}}

var map-to-pass map[string] StringInterface // THIS I DON'T KNOW, CAST *Staff TO *blahstring
//=== importer/utils

func DumpTextFile(string fileName, MAP //THIS I DON'T KNOW) {
  for k, v := range map{
    FILE.WRITESTRING(V.String())
  }
}


Sound bad this way, I like yours better, but one thing I do in importer/utils is to have the "file management" (read and write to files)

If I do it the other way, I would have the Contents() function in utils and the WriteToFile function in importer.

Does this makes any sence? I am beginning to doubt it

André Moraes

unread,
Nov 10, 2010, 2:51:07 PM11/10/10
to Francisco Diaz Trepat - gmail, golang-nuts
My example I was doing the oposite way... Reading the file and processing it.

But looks like you want to save the map structure to a file.

In that case, you can do this:

== import/utils

type Dumper interface {
  Dump() string
}

type MyFile struct {
  target bufio.Writer
}

func (d *MyFile) Save(d Dumper) {
  target.WriteString(d.Dump())
}

func NewFile(fileName string) *MyFile {
  var file bufio.Writer
  // create the file and return the MyFile object
  return &MyFile{target:file}
}

== import

type Staff struct {
  name string,
  blah string
}

func (s *Staff) Dump() string {
  return s.name + ":" + s.blah
}

func DumpStaff() {
  staff := map[string]Staff{"a":Staff{name:"andre",blah:"blah"}}
  myfile := utils.NewFile("staff.dump")
  for _, v range staff {
    myfile.Save(v)
  }
}

This way, the import/utils require only the implementation of the Dumper interface. 

So the logic to actually write the information on the file is in "utils" but the logic to serialiaze the object to string is defined by each object.

Francisco Diaz Trepat - gmail

unread,
Nov 10, 2010, 3:11:03 PM11/10/10
to André Moraes, golang-nuts
Awesome, also much more clear that way.

2010/11/10 André Moraes <and...@gmail.com>

Francisco Diaz Trepat - gmail

unread,
Nov 10, 2010, 4:21:42 PM11/10/10
to André Moraes, golang-nuts
How do I mount the bufio.Writer to the *os.File?

Do I have to flush it?

f(t)

2010/11/10 André Moraes <and...@gmail.com>
My example I was doing the oposite way... Reading the file and processing it.

André Moraes

unread,
Nov 10, 2010, 4:24:35 PM11/10/10
to Francisco Diaz Trepat - gmail, golang-nuts
mybuff := bufio.NewWriter(myFileObj)

Yes, you need to flush it

2010/11/10 Francisco Diaz Trepat - gmail <francisco....@gmail.com>
How do I mount the bufio.Writer to the *os.File?

Do I have to flush it?

Reply all
Reply to author
Forward
0 new messages