Mastering Formatted and File I/O in Go
Arya Pathak
Backend Dev ? Open Source ? Compilers ? .Net ? Go ? Angular ? Azure ? AWS ? Cybersecurity ? Ethereum???VIT?Pune '26
In this article, we'll delve into the world of formatted and file I/O in Go. We'll explore the powerful fmt package for formatted I/O and the os and io packages for file operations. Along the way, we'll demonstrate these concepts with plenty of code examples to illustrate how they work and why they're useful.
Standard I/O Streams in Go
Go, like many modern programming languages, provides access to standard I/O streams: standard input, standard output, and standard error. These are exposed via the os package as os.Stdin , os.Stdout, and os.Stderr. Let's start by understanding the basic usage of these streams.
Printing to Standard Output
The fmt package provides several functions for printing to the console. The most basic is fmt.Println, which prints its arguments followed by a newline. For more control over formatting, we use fmt.Printf.
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("This is printed to standard output.")
// Using Printf for formatted output
name := "Alice"
age := 30
fmt.Printf("Name: %s, Age: %d\n", name, age)
// Redirecting output to standard error
fmt.Fprintf(os.Stderr, "This is an error message.\n")
}
Formatting Strings with fmt
The fmt package includes functions like fmt.Sprintf, which returns a formatted string instead of printing it. This is useful when you need to store the formatted string for later use.
func main() {
name := "Alice"
age := 30
formattedString := fmt.Sprintf("Name: %s, Age: %d", name, age)
fmt.Println(formattedString)
}
Formatting Verbs in Go
Formatting verbs in Go are placeholders within a format string. Here are some common verbs:
func main() {
// Formatting integers
number := 255
fmt.Printf("Decimal: %d, Hex: %x, Binary: %b\n", number, number, number)
// Formatting floating-point numbers
pi := 3.14159
fmt.Printf("Default float: %f, Two decimals: %.2f\n", pi, pi)
// Formatting booleans and generic values
isTrue := true
fmt.Printf("Boolean: %t, Generic: %v\n", isTrue, isTrue)
}
File I/O in Go
File I/O in Go is straightforward with the os package. Let's start with reading files.
领英推荐
Reading Files
To read a file, we use os.Open to get a file handle and bufio.NewScanner to read it line by line.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening file: %v\n", err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Fprintf(os.Stderr, "Error reading file: %v\n", err)
}
}
Writing Files
To write to a file, we use os.Create to create or truncate the file, and fmt.Fprintf to write to it.
func main() {
file, err := os.Create("output.txt")
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating file: %v\n", err)
return
}
defer file.Close()
fmt.Fprintf(file, "This is a line of text.\n")
fmt.Fprintf(file, "This is another line of text.\n")
}
Using io/ioutil for Simple File Operations
The io/ioutil package provides convenient functions for simple file operations, like reading an entire file into memory.
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
data, err := ioutil.ReadFile("example.txt")
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading file: %v\n", err)
return
}
fmt.Println(string(data))
err = ioutil.WriteFile("output.txt", data, 0644)
if err != nil {
fmt.Fprintf(os.Stderr, "Error writing file: %v\n", err)
}
}
Building a Simple cat Program
Let's combine these concepts to build a simple version of the Unix cat command, which reads files and prints their contents to standard output.
package main
import (
"fmt"
"io"
"os"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <file1> <file2> ...\n", os.Args[0])
os.Exit(1)
}
for _, filename := range os.Args[1:] {
file, err := os.Open(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening file %s: %v\n", filename, err)
continue
}
if _, err := io.Copy(os.Stdout, file); err != nil {
fmt.Fprintf(os.Stderr, "Error reading file %s: %v\n", filename, err)
}
file.Close()
}
}
Building a Word Count Program
We'll now create a program that mimics the Unix wc command, counting lines, words, and characters in a file.
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: %s <file1> <file2> ...\n", os.Args[0])
os.Exit(1)
}
for _, filename := range os.Args[1:] {
file, err := os.Open(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening file %s: %v\n", filename, err)
continue
}
lines, words, chars := 0, 0, 0
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines++
text := scanner.Text()
words += len(strings.Fields(text))
chars += len(text)
}
if err := scanner.Err(); err != nil {
fmt.Fprintf(os.Stderr, "Error reading file %s: %v\n", filename, err)
}
fmt.Printf("%d %d %d %s\n", lines, words, chars, filename)
file.Close()
}
}
In this article, we've covered the basics of formatted and file I/O in Go. We explored the fmt package for printing and formatting strings and the os and io packages for file operations. We also built simple versions of the Unix cat and wc commands to demonstrate these concepts in action. With these tools, you can handle a wide range of I/O tasks in your Go programs.
Teaching Ai @ CompleteAiTraining.com | Building AI Solutions @ Nexibeo.com
7 个月Great insights in your post! File I/O can be tricky, but mastering it opens up a world of possibilities. I recently explored similar topics in my article: https://completeaitraining.com/blog/everything-you-need-to-know-about-formatted-io-and-file-operations-in-go. Keep up the good work!