YouTip LogoYouTip

Go File Handle

File handling is one of the most common operations in Goβ€”reading configurations, writing logs, and data persistence allcannot do without it. Go's standard library provides a concise yet powerful set of file I/O interfaces, covering scenarios from single read/write operations to streaming processing. There are 5 core packages related to file handling, each with its own responsibilities: > **Version Note:** The `ioutil` package was deprecated in Go 1.16, and its functionality has been migrated to `os` (such as `os.ReadFile`, `os.WriteFile`) and `io` (such as `io.ReadAll`). New code should directly use the `os` and `io` packages. * * * ## 1. File Creation `os.Create` creates a new file. If the file already exists, it will be truncated (content cleared). The returned file object must be closed to release system resources: ## Example package main import( "log" "os" ) func main(){ // os.Create creates a file (existing file will be cleared) file, err := os.Create("test.txt") if err !=nil{ log.Fatal(err) } defer file.Close()// defer ensures file is closed when function ends // Write content to verify creation succeeded file.WriteString("File created successfullyn") log.Println("File created successfully") } > **`defer file.Close()`** is the best practice for Go file operations. `defer` ensures that even if subsequent code panics, the file will be properly closed, avoiding file descriptor leaks. * * * ## 2. File Opening and Closing The `os` package provides three ways to open files, suitable for different scenarios: | Function | Mode | Description | | --- | --- | --- | | `os.Open(name)` | Read-only | Simplest way, opens for reading only | | `os.Create(name)` | Read/Write + Create/Truncate | Creates new file or clears existing file | | `os.OpenFile(name, flag, perm)` | Custom | Can specify read/write, append, create and other flags | ## Example package main import( "fmt" "os" ) func main(){ // Method 1: Open for reading only file, err := os.Open("example.txt") if err !=nil{ fmt.Println("Failed to open:", err) return } defer file.Close() fmt.Println("File opened successfully") // Method 2: OpenFile with custom mode // os.O_WRONLY write-only // os.O_CREATE create if not exists // os.O_APPEND append mode // os.O_TRUNC truncate if exists f, err := os.OpenFile("log.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND,0644) if err !=nil{ fmt.Println("Failed to open:", err) return } defer f.Close() f.WriteString("Append a log linen") } ### OpenFile Flag Description | Flag | Description | | --- | --- | | `os.O_RDONLY` | Read-only (default) | | `os.O_WRONLY` | Write-only | | `os.O_RDWR` | Read-write | | `os.O_APPEND` | Append mode, appends content to end of file | | `os.O_CREATE` | Create file if it doesn't exist | | `os.O_TRUNC` | Clear file content when opening | | `os.O_EXCL` | Used with CREATE, returns error if file already exists | * * * ## 3. File Reading Go provides three main ways to read files, choose based on file size and processing requirements: ### 3.1 Read Entire File at Once (Recommended for Small Files) `os.ReadFile` is the simplest wayβ€”automatically opens, reads, and closes the file in one step: ## Example package main import( "fmt" "log" "os" ) func main(){ // Read entire file at once (Go 1.16+) data, err := os.ReadFile("config.json") if err !=nil{ log.Fatal(err) } fmt.Println(string(data)) } ### 3.2 Read Line by Line (Recommended for Large Files) For large files, use `bufio.Scanner` to process line by line, avoiding loading everything into memory at once: ## Example package main import( "bufio" "fmt" "log" "os" ) func main(){ file, err := os.Open("large-file.log") if err !=nil{ log.Fatal(err) } defer file.Close() // Scan line by line scanner := bufio.NewScanner(file) lineNum :=0 for scanner.Scan(){ lineNum++ line := scanner.Text()// Get current line content fmt.Printf("Line %d: %sn", lineNum, line) } // Check for errors during scanning if err := scanner.Err(); err !=nil{ log.Fatal("Read error:", err) } } > **Note:** `bufio.Scanner` has a default maximum line length of 64KB. If your file has lines longer than that, you need to call `scanner.Buffer(make([]byte, 0), maxSize)` before calling `Scan()` to increase the buffer size. ### 3.3 Using io.ReadAll to Read When you already have an open `io.Reader` (such as a network response or an opened file), you can use `io.ReadAll`: ## Example package main import( "fmt" "io" "log" "os" ) func main(){ file, err := os.Open("example.txt") if err !=nil{ log.Fatal(err) } defer file.Close() // Read all data from Reader data, err := io.ReadAll(file) if err !=nil{ log.Fatal(err) } fmt.Println(string(data)) } * * * ## 4. File Writing Go provides multiple writing methods, from simple one-time writes to high-performance buffered writes: ### 4.1 One-Time Write `os.WriteFile` writes data to a file in one go (overwrites existing content): ## Example package main import( "log" "os" ) func main(){ content :=[]byte("Hello, Go!n This is the second linen") // 0644: owner read/write, others read-only err := os.WriteFile("output.txt", content,0644) if err !=nil{ log.Fatal(err) } log.Println("Write successful") } ### 4.2 Using File Object to Write Through the file object, you can write content in multiple steps: ## Example package main import( "fmt" "log" "os" ) func main(){ file, err := os.Create("output.txt") if err !=nil{ log.Fatal(err) } defer file.Close() // Method 1: Write string file.WriteString("Write string directlyn") // Method 2: Write byte slice data :=[]byte("Write byte slicen") file.Write(data) // Method 3: Formatted write fmt.Fprintf(file,"Formatted write: %d + %d = %dn",3,4,7) } ### 4.3 Buffered Write (Recommended for Large Amounts of Data) `bufio.Writer` first writes data to a memory buffer, then batch writes to disk when the buffer is full, significantly reducing I/O operations. Be sure to call `Flush()` before finishing: ## Example package main import( "bufio" "log" "os" ) func main(){ file, err := os.Create("buffered-output.txt") if err !=nil{ log.Fatal(err) } defer file.Close() // Create buffered writer writer := bufio.NewWriter(file) // Write multiple lines (go to buffer first, not immediately to disk) for i:=0;i<1000;i++{ writer.WriteString("This is line "+ itoa(i)+"n") } // Flush writes remaining buffer data to file if err := writer.Flush(); err !=nil{ log.Fatal("Failed to flush buffer:", err) } log.Println("Buffered write completed") } // Simple int to string helper function func itoa(n int)string{ return fmt.Sprintf("%d", n) } * * * ## 5. File Append Writing Use the `os.O_APPEND` flag to append content at the end of the file without overwriting existing data: ## Example package main import( "log" "os" "time" ) func main(){ // O_APPEND: append mode // O_CREATE: create if not exists // O_WRONLY: write-only file,
← Go Type AssertionLinux Quiz β†’