File Operations

Back

Loading concept...

πŸ“‚ Golang File and IO Operations

Your Complete Guide to Working with Files


🎭 The Story: You Are a Librarian

Imagine you’re a librarian in a magical library. Every book is a file. You can:

  • Read books to learn what’s inside
  • Write new books or add pages to existing ones
  • Control who can access each book (permissions)
  • Navigate through shelves and sections (paths)
  • Use special tools to read faster (buffered IO)
  • Follow standard rules for organizing everything (interfaces)

Let’s explore this library together! πŸ›οΈ


πŸ“– 1. File Reading

What Is It?

Reading a file means opening a book and looking at its pages. Go gives you several ways to peek inside files.

The Simplest Way: Read Everything at Once

package main

import (
    "fmt"
    "os"
)

func main() {
    // Read the whole file at once
    data, err := os.ReadFile("story.txt")
    if err != nil {
        fmt.Println("Oops!", err)
        return
    }
    fmt.Println(string(data))
}

Think of it like: Photocopying an entire book in one go!

Reading Piece by Piece

file, err := os.Open("story.txt")
if err != nil {
    fmt.Println("Can't open:", err)
    return
}
defer file.Close() // Always close!

buffer := make([]byte, 100)
for {
    n, err := file.Read(buffer)
    if err != nil {
        break
    }
    fmt.Print(string(buffer[:n]))
}

Think of it like: Reading one chapter at a time!

πŸ”‘ Key Points

  • os.ReadFile() β†’ Quick and easy for small files
  • os.Open() β†’ When you need more control
  • Always close files! Use defer file.Close()

✍️ 2. File Writing

What Is It?

Writing to a file means adding new pages to a book or creating a brand new book.

The Quickest Way: Write Everything

package main

import "os"

func main() {
    message := []byte("Hello, World!")
    err := os.WriteFile("hello.txt", message, 0644)
    if err != nil {
        panic(err)
    }
}

Creating and Writing Step by Step

// Create a new file
file, err := os.Create("diary.txt")
if err != nil {
    panic(err)
}
defer file.Close()

// Write to it
file.WriteString("Day 1: Learning Go!\n")
file.Write([]byte("Day 2: Files are fun!\n"))

Appending (Adding to the End)

file, err := os.OpenFile("diary.txt",
    os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
    panic(err)
}
defer file.Close()

file.WriteString("Day 3: I'm getting better!\n")

Think of it like: Adding new pages to your diary without erasing old ones!


πŸ” 3. File Modes and Permissions

What Are They?

Permissions are like library rules: who can read, write, or enter certain sections.

Understanding Permission Numbers

Permission: 0644
          ↓
   Owner: 6 (read + write)  = rw-
   Group: 4 (read only)     = r--
   Others: 4 (read only)    = r--

Common Permission Codes

Code Owner Group Others Use Case
0644 rw- r– r– Regular files
0755 rwx r-x r-x Executable files
0600 rw- β€” β€” Private files

File Open Flags

// Flags you can combine with |
os.O_RDONLY  // Read only
os.O_WRONLY  // Write only
os.O_RDWR    // Read and write
os.O_CREATE  // Create if missing
os.O_APPEND  // Add to end
os.O_TRUNC   // Erase first

Example: Specific Permissions

file, err := os.OpenFile("secret.txt",
    os.O_CREATE|os.O_WRONLY,
    0600) // Only owner can read/write

πŸ—ΊοΈ 4. Path Manipulation

What Is It?

Paths are directions to find books in our library. The filepath package helps you navigate!

Building Paths Safely

import "path/filepath"

// Join paths the right way
path := filepath.Join("home", "user", "docs")
// Result: "home/user/docs" (or "home\user\docs" on Windows)

Why use Join? It automatically uses the right slash for your operating system!

Useful Path Operations

fullPath := "/home/user/docs/report.pdf"

// Get the directory
dir := filepath.Dir(fullPath)
// Result: "/home/user/docs"

// Get the filename
name := filepath.Base(fullPath)
// Result: "report.pdf"

// Get the extension
ext := filepath.Ext(fullPath)
// Result: ".pdf"

// Get absolute path
abs, _ := filepath.Abs("./file.txt")
// Result: Full path from root

Walking Through Directories

filepath.Walk("/home/user", func(
    path string,
    info os.FileInfo,
    err error) error {

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

Think of it like: Walking through every aisle in the library!


πŸ”Œ 5. IO Interfaces

What Are They?

Interfaces are standard plugs that let different things work together. The two most important are:

The Reader Interface

type Reader interface {
    Read(p []byte) (n int, err error)
}

Anything that can be read from implements this:

  • Files
  • Network connections
  • Strings
  • HTTP responses

The Writer Interface

type Writer interface {
    Write(p []byte) (n int, err error)
}

Anything you can write to implements this.

Why Interfaces Are Magic

import "io"

// This function works with ANY reader!
func countBytes(r io.Reader) (int, error) {
    buf := make([]byte, 1024)
    total := 0
    for {
        n, err := r.Read(buf)
        total += n
        if err != nil {
            break
        }
    }
    return total, nil
}

Copying Data Easily

// Copy from any Reader to any Writer
io.Copy(destinationWriter, sourceReader)

// Example: Copy file
src, _ := os.Open("source.txt")
dst, _ := os.Create("copy.txt")
io.Copy(dst, src)

πŸš€ 6. Buffered IO

What Is It?

Buffered IO is like having a shopping cart. Instead of making one trip per item, you collect items and make fewer trips!

Why Buffering Matters

Without buffering: 100 small writes = 100 disk operations 😰 With buffering: 100 small writes = 1 disk operation! πŸŽ‰

Buffered Reading

import "bufio"

file, _ := os.Open("bigfile.txt")
reader := bufio.NewReader(file)

// Read line by line efficiently
for {
    line, err := reader.ReadString('\n')
    if err != nil {
        break
    }
    fmt.Print(line)
}

Buffered Writing

file, _ := os.Create("output.txt")
writer := bufio.NewWriter(file)

writer.WriteString("Line 1\n")
writer.WriteString("Line 2\n")
writer.WriteString("Line 3\n")

// DON'T FORGET: Flush sends data to disk!
writer.Flush()
file.Close()

Scanner: The Easiest Way to Read Lines

file, _ := os.Open("list.txt")
scanner := bufio.NewScanner(file)

for scanner.Scan() {
    line := scanner.Text()
    fmt.Println("Found:", line)
}

Pro Tip: Scanner handles line endings automatically! 🎯


πŸ“ 7. The io/fs Package

What Is It?

The io/fs package provides a universal way to work with any file system β€” real files, embedded files, zip archives, or even remote storage!

The FS Interface

type FS interface {
    Open(name string) (File, error)
}

Working with the OS File System

import "io/fs"

// Walk through files
fs.WalkDir(os.DirFS("."), ".", func(
    path string,
    d fs.DirEntry,
    err error) error {

    fmt.Println(path)
    return nil
})

Reading Files from Any FS

// Create a filesystem rooted at a directory
myFS := os.DirFS("/home/user/data")

// Read a file from it
data, err := fs.ReadFile(myFS, "config.json")

Checking File Info

info, err := fs.Stat(myFS, "file.txt")
if err != nil {
    panic(err)
}

fmt.Println("Name:", info.Name())
fmt.Println("Size:", info.Size())
fmt.Println("Is Dir:", info.IsDir())
fmt.Println("Mode:", info.Mode())

Embedded Files (Super Cool!)

import "embed"

//go:embed templates/*
var templates embed.FS

// Now use templates as a filesystem!
data, _ := fs.ReadFile(templates, "templates/index.html")

Think of it like: One remote control that works with every TV brand!


🎯 Quick Summary

graph LR A["πŸ“‚ File Operations"] --> B["πŸ“– Reading"] A --> C["✍️ Writing"] A --> D["πŸ” Permissions"] A --> E["πŸ—ΊοΈ Paths"] A --> F["πŸ”Œ Interfaces"] A --> G["πŸš€ Buffered IO"] A --> H["πŸ“ io/fs"] B --> B1["os.ReadFile"] B --> B2["os.Open + Read"] C --> C1["os.WriteFile"] C --> C2["os.Create"] C --> C3["Append mode"] F --> F1["io.Reader"] F --> F2["io.Writer"] G --> G1["bufio.Reader"] G --> G2["bufio.Writer"] G --> G3["bufio.Scanner"]

🌟 You Did It!

You now understand how Go handles files like a pro librarian:

  1. Read files quickly or piece by piece
  2. Write new content or append to existing files
  3. Control access with permissions and modes
  4. Navigate paths safely across any OS
  5. Use interfaces for flexible, reusable code
  6. Buffer your IO for speed
  7. Abstract filesystems with io/fs

Next step: Try creating a small program that reads a file, modifies it, and writes it back! You’ve got this! πŸ’ͺ

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.