EZ

Eduzan

Learning Hub

Eduzan
Eduzan / Go Programming Language

File Handling in GO

1. Reading an Entire File into Memory

The simplest file operation is reading an entire file into memory using the os.ReadFile function. Below is an example.

Directory Structure

├── Workspace
│   └── filedemo
│       ├── main.go
│       ├── go.mod
│       └── sample.txt

Content of sample.txt:

Welcome to Go file handling!

Code in main.go:

package main

import (
	"fmt"
	"os"
)

func main() {
	content, err := os.ReadFile("sample.txt")
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	fmt.Println("File content:", string(content))
}

Run Instructions:

cd ~/Workspace/filedemo/
go install
filedemo

Output:

File content: Welcome to Go file handling!

If you run the program from a different directory, you’ll encounter:

Error reading file: open sample.txt: no such file or directory

2. Using an Absolute File Path

Using an absolute path ensures the program works regardless of the current directory.

Updated Code in main.go:

package main

import (
	"fmt"
	"os"
)

func main() {
	content, err := os.ReadFile("/Users/user/Workspace/filedemo/sample.txt")
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	fmt.Println("File content:", string(content))
}

Output:

File content: Welcome to Go file handling!

3. Passing the File Path as a Command-Line Argument

Using the flag package, we can pass the file path dynamically.

Code in main.go:

package main

import (
	"flag"
	"fmt"
	"os"
)

func main() {
	filePath := flag.String("file", "sample.txt", "Path of the file to read")
	flag.Parse()

	content, err := os.ReadFile(*filePath)
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	fmt.Println("File content:", string(content))
}

Run Instructions:

filedemo --file=/path/to/sample.txt

Output:

File content: Welcome to Go file handling!

4. Bundling the File within the Binary

Using the embed package, we can include the file contents directly in the binary.

Code in main.go:

package main

import (
	_ "embed"
	"fmt"
)

//go:embed sample.txt
var fileData []byte

func main() {
	fmt.Println("File content:", string(fileData))
}

Compile and run the binary:

cd ~/Workspace/filedemo/
go install
filedemo

Output:

File content: Welcome to Go file handling!

5. Reading a File in Small Chunks

For large files, read them in chunks using the bufio package.

Code in main.go:

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
)

func main() {
	filePath := flag.String("file", "sample.txt", "Path of the file to read")
	flag.Parse()

	file, err := os.Open(*filePath)
	if err != nil {
		fmt.Println("Error opening file:", err)
		return
	}
	defer file.Close()

	reader := bufio.NewReader(file)
	buffer := make([]byte, 5)

	for {
		bytesRead, err := reader.Read(buffer)
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Println("Error reading file:", err)
			return
		}
		fmt.Print(string(buffer[:bytesRead]))
	}
	fmt.Println("\nFile read completed.")
}

6. Reading a File Line by Line

To process large files line by line, use a bufio.Scanner.

Code in main.go:

package main

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

func main() {
	filePath := flag.String("file", "sample.txt", "Path of the file to read")
	flag.Parse()

	file, err := os.Open(*filePath)
	if err != nil {
		fmt.Println("Error opening file:", err)
		return
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		fmt.Println("Error reading file:", err)
	}
}

Run Instructions:

filedemo --file=/path/to/sample.txt

Output:

Welcome to Go file handling!
End of lesson.