Go > File and I/O > Standard Input/Output > bufio Scanner and Writer
Reading from a File Line by Line with bufio.Scanner
This snippet demonstrates how to efficiently read a file line by line using `bufio.Scanner` in Go. It covers opening the file, reading its content, and handling potential errors.
Basic Usage of bufio.Scanner for File Reading
This code opens a file named `input.txt`, creates a `bufio.Scanner` to read it line by line, and prints each line to the console. The `defer file.Close()` ensures the file is closed when the function exits, even if errors occur. The `scanner.Err()` checks for errors during the scanning process, which is crucial for robust error handling.
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
file, err := os.Open("input.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
Concepts Behind bufio.Scanner
bufio.Scanner
provides a convenient interface for reading data from an io.Reader
, such as a file. It splits the data into tokens (by default, lines) and allows you to iterate through them. The key methods are NewScanner
to create a scanner, Scan
to read the next token, Text
to retrieve the token as a string, and Err
to check for errors.
Real-Life Use Case
Parsing log files is a common real-world use case. Imagine needing to analyze a large log file. Using bufio.Scanner
lets you process the file line by line without loading the entire file into memory, making it efficient for large files. You can then apply regular expressions or other parsing techniques to extract specific information from each log entry.
Best Practices
scanner.Err()
to check for errors that might have occurred during scanning.defer file.Close()
to ensure the file is closed properly.scanner.Split()
.
Interview Tip
Be prepared to discuss the advantages of using bufio.Scanner
over reading the entire file into memory at once. Also, understand how to handle errors and potential edge cases, such as very large lines.
When to Use bufio.Scanner
Use bufio.Scanner
when you need to process text-based data from an io.Reader
(like a file, network connection, or standard input) line by line or using a custom delimiter. It's particularly useful when dealing with large files that you don't want to load entirely into memory.
Memory Footprint
bufio.Scanner
is memory-efficient because it reads data in chunks rather than loading the entire file into memory. This makes it suitable for processing large files without consuming excessive memory.
Alternatives
io.ReadAll
: Reads the entire file into memory at once. Suitable for small files but inefficient for large ones.bufio.Reader
: Provides more control over buffering and reading, but requires more manual handling of newline characters.
Pros
Cons
bufio.Reader
.
FAQ
-
How do I handle errors when using bufio.Scanner?
Always check the error returned byos.Open
when opening the file. After the scanning loop, callscanner.Err()
to check for errors that might have occurred during the scanning process. Uselog.Fatal
to handle critical errors that prevent the program from continuing. -
How can I split the input by something other than lines?
You can use thescanner.Split()
method with a custom split function. Thebufio
package provides some predefined split functions likebufio.ScanWords
. You can also create your own split function to handle more complex delimiters.