BudiBadu Logo

Samplebadu

Code with Example
BudiBadu Logo
Samplebadu

Go by Example: File Reading and Writing

Go 1.23

Learn File I/O operations in Go. This comprehensive example demonstrates reading files entirely, reading in chunks, and processing line-by-line using `bufio`, as well as creating and writing data to files using the `os` package.

Code

package main

import (
    "bufio"
    "fmt"
    "os"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func main() {
    // --- Writing Files ---
    
    // Write a string to a file
    d1 := []byte("hello\ngo\n")
    err := os.WriteFile("dat1.txt", d1, 0644)
    check(err)

    // Open file for more granular writing
    f, err := os.Create("dat2.txt")
    check(err)
    defer f.Close()

    // Write byte slice
    d2 := []byte{115, 111, 109, 101, 10}
    n2, err := f.Write(d2)
    check(err)
    fmt.Printf("wrote %d bytes\n", n2)

    // Write string
    n3, err := f.WriteString("writes\n")
    check(err)
    fmt.Printf("wrote %d bytes\n", n3)

    // Flush writes to stable storage
    f.Sync()

    // --- Reading Files ---

    // Read entire file into memory
    dat, err := os.ReadFile("dat1.txt")
    check(err)
    fmt.Print(string(dat))

    // Open file for granular reading
    f2, err := os.Open("dat1.txt")
    check(err)
    defer f2.Close()

    // Read first 5 bytes
    b1 := make([]byte, 5)
    n1, err := f2.Read(b1)
    check(err)
    fmt.Printf("%d bytes: %s\n", n1, string(b1[:n1]))

    // Seek to a known location
    o2, err := f2.Seek(6, 0)
    check(err)
    b2 := make([]byte, 2)
    n2, err = f2.Read(b2)
    check(err)
    fmt.Printf("%d bytes @ %d: ", n2, o2)
    fmt.Printf("%v\n", string(b2[:n2]))

    // Buffered reading (efficient for many small reads)
    r4 := bufio.NewReader(f2)
    b4, err := r4.Peek(5)
    check(err)
    fmt.Printf("5 bytes: %s\n", string(b4))
}

Explanation

Go provides comprehensive file I/O support in the os package. The approach you choose depends on the file size and your specific needs:

  • Small Files: Use os.ReadFile and os.WriteFile. These are convenient one-liners that handle opening, reading/writing the entire file, and closing it automatically.
  • Large Files & Streams: Use os.Open with bufio.NewScanner or bufio.Reader. This allows you to process data chunk-by-chunk or line-by-line without loading the entire file into memory, preventing OOM errors.
  • Fine Control: Use os.File methods (Seek, ReadAt) when you need random access to specific parts of a file.

Under the hood, Go's I/O is built around the io.Reader and io.Writer interfaces. This powerful abstraction allows you to treat files, network connections, and in-memory buffers identically, making your code highly reusable and testable.

Code Breakdown

20
os.WriteFile is a helper that creates/truncates the file, writes the data, and closes it. 0644 is the file permission (rw-r--r--).
40
Sync() commits the current contents of the file to stable storage (flush). This ensures data is physically written to disk.
61
Seek sets the offset for the next Read or Write. The second argument 0 means relative to the origin of the file.
70
bufio.NewReader creates a buffered reader. Peek returns the next n bytes without advancing the reader position.