Esta pagina se ve mejor con JavaScript habilitado

Go writing files

 ·  🎃 kr0m

Escribir ficheros es una de las operaciones mas comunes en Go, en este artículo aprenderemos las distintas posibilidades que nos ofrece para hacerlo.

El artículo se compone de varias secciones:


Si eres nuevo en el mundo de Go te recomiendo los siguientes artículos anteriores:


Escribir un string:

El código es bastante auto explicativo.

package main

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.Create("test.txt")
    if err != nil {
        fmt.Println(err)
        return
    }

    l, err := f.WriteString("Hello World\n")
    if err != nil {
        fmt.Println(err)
        f.Close()
        return
    }

    fmt.Println(l, "bytes written successfully")

    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}
12 bytes written successfully
cat test.txt
Hello World

Escribir bytes:

Escribir una secuencia de bytes es muy similar al ejemplo anterior, tan solo debemos crear el slice de bytes y escribirlos.

package main

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.Create("test.txt")
    if err != nil {
        fmt.Println(err)
        return
    }

    d2 := []byte{72, 101, 108, 108, 111, 32, 66, 121, 116, 101, 115, 10}
    n2, err := f.Write(d2)
    if err != nil {
        fmt.Println(err)
        f.Close()
        return
    }

    fmt.Println(n2, "bytes written successfully")

    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}
12 bytes written successfully
cat test.txt
Hello Bytes

Escribir línea a línea:

Para escribir por líneas vamos a crear un slice con cada una de las líneas y las escribiremos mediante la función fmt.Fprintln() que recibe como primer parámetro de entrada el descriptor del fichero a escribir y como segundo parámetro la línea a escribir.

package main

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.Create("test.txt")
    if err != nil {
        fmt.Println(err)
        f.Close()
        return
    }

    d := []string{"Welcome to the world of Go1.", "Go is a compiled language.", "It is easy to learn Go."}

    for _, v := range d {
        fmt.Fprintln(f, v)
        if err != nil {
            fmt.Println(err)
            return
        }
    }

    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("File written successfully")
}
File written successfully
cat test.txt
Welcome to the world of Go1.
Go is a compiled language.
It is easy to learn Go.

Añadir contenido:

Para añadir contenido a un fichero previamente existente no debemos utilizar la función os.Create(), si no os.OpenFile().
Debemos indicar el fichero, el modo de acceso y los permisos. Estos serán utilizados en caso de que el fichero no exista y se haya especificado el modo O_CREATE, si existe previamente se dejan los permisos existentes. Incluso cuando no se utiliza el modo O_CREATE como es el caso, la función nos fuerza a indicar unos permisos.

package main

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.OpenFile("test.txt", os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        fmt.Println(err)
        return
    }

    newLine := "File handling is easy."
    _, err = fmt.Fprintln(f, newLine)
    if err != nil {
        fmt.Println(err)
                f.Close()
        return
    }

    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("File appended successfully")
}
File appended successfully
cat test.txt
Already existent line
File handling is easy.

Escrituras concurrentes:

Escribir en paralelo es tan sencillo como llamar a la función encargada de escribir mediante go routines , tan solo debemos tener en cuenta que hay que utilizar un waitGroup para controlar cuando han acabado todas ellas de escribir.

package main

import (
    "fmt"
    "os"
    "strconv"
    "sync"
)

func writeLine(f *os.File, newLine string, wg *sync.WaitGroup) {
    _, err := fmt.Fprintln(f, newLine)
    wg.Done()
    if err != nil {
        fmt.Println(err)
    }
}

func main() {
    f, err := os.OpenFile("test.txt", os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        fmt.Println(err)
        return
    }

    wg := sync.WaitGroup{}
    for i := 1; i <= 300; i++ {
        newLine := "Line: " + strconv.Itoa(i)
        wg.Add(1)
        go writeLine(f, newLine, &wg)
    }
    wg.Wait()

    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("File appended successfully")
}
File appended successfully
wc -l test.txt
     300 test.txt
Si te ha gustado el artículo puedes invitarme a un RedBull aquí