Working with Files in Go
Go provides robust file handling capabilities through the os
and io/ioutil
packages. This guide covers common file operations and best practices.
Basic File Operations
Opening and Closing Files
func openFile() error {
// Open file for reading
file, err := os.Open("input.txt")
if err != nil {
return fmt.Errorf("opening file: %w", err)
}
defer file.Close()
// Open file for writing
writeFile, err := os.Create("output.txt")
if err != nil {
return fmt.Errorf("creating file: %w", err)
}
defer writeFile.Close()
return nil
}
Reading Files
// Read entire file
func readEntireFile(filename string) ([]byte, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("reading file: %w", err)
}
return data, nil
}
// Read file line by line
func readLines(filename string) error {
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("opening file: %w", err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// Process line
fmt.Println(line)
}
return scanner.Err()
}
Writing Files
// Write entire file
func writeFile(filename string, data []byte) error {
err := os.WriteFile(filename, data, 0644)
if err != nil {
return fmt.Errorf("writing file: %w", err)
}
return nil
}
// Write file line by line
func writeLines(filename string, lines []string) error {
file, err := os.Create(filename)
if err != nil {
return fmt.Errorf("creating file: %w", err)
}
defer file.Close()
writer := bufio.NewWriter(file)
for _, line := range lines {
_, err := writer.WriteString(line + "\n")
if err != nil {
return fmt.Errorf("writing line: %w", err)
}
}
return writer.Flush()
}
File Information
Getting File Info
func getFileInfo(filename string) error {
info, err := os.Stat(filename)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("file does not exist: %w", err)
}
return fmt.Errorf("getting file info: %w", err)
}
fmt.Printf("Name: %s\n", info.Name())
fmt.Printf("Size: %d bytes\n", info.Size())
fmt.Printf("Mode: %s\n", info.Mode())
fmt.Printf("Modified: %s\n", info.ModTime())
fmt.Printf("Is Directory: %t\n", info.IsDir())
return nil
}
Checking File Existence
func fileExists(filename string) bool {
_, err := os.Stat(filename)
return !os.IsNotExist(err)
}
Directory Operations
Creating Directories
func createDirs() error {
// Create single directory
err := os.Mkdir("newdir", 0755)
if err != nil {
return fmt.Errorf("creating directory: %w", err)
}
// Create directory with parents
err = os.MkdirAll("path/to/nested/dir", 0755)
if err != nil {
return fmt.Errorf("creating nested directories: %w", err)
}
return nil
}
Reading Directory Contents
func listDirectory(path string) error {
entries, err := os.ReadDir(path)
if err != nil {
return fmt.Errorf("reading directory: %w", err)
}
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
return fmt.Errorf("getting entry info: %w", err)
}
fmt.Printf("Name: %s, Size: %d, IsDir: %t\n",
info.Name(), info.Size(), info.IsDir())
}
return nil
}
File Permissions
Setting Permissions
func setPermissions(filename string) error {
// Set file permissions (read/write for owner, read for others)
err := os.Chmod(filename, 0644)
if err != nil {
return fmt.Errorf("setting permissions: %w", err)
}
return nil
}
Changing Ownership
func changeOwnership(filename string) error {
// Change file owner and group
err := os.Chown(filename, uid, gid)
if err != nil {
return fmt.Errorf("changing ownership: %w", err)
}
return nil
}
Best Practices
Always Close Files
file, err := os.Open("file.txt") if err != nil { return err } defer file.Close()
Use Buffered IO for Performance
file, err := os.Create("large-file.txt") if err != nil { return err } defer file.Close() writer := bufio.NewWriter(file) defer writer.Flush()
Handle Temporary Files
tempFile, err := os.CreateTemp("", "prefix-*.txt") if err != nil { return err } defer os.Remove(tempFile.Name()) defer tempFile.Close()
Check File Size Before Reading
func readIfNotTooLarge(filename string, maxSize int64) ([]byte, error) { info, err := os.Stat(filename) if err != nil { return nil, err } if info.Size() > maxSize { return nil, fmt.Errorf("file too large") } return os.ReadFile(filename) }
Next Steps
- Learn about IO Operations
- Explore JSON Processing
- Study Template Engine