package main import ( "bufio" "fmt" "os" "path/filepath" ) // appendLine 以追加方式写入一行,写完后关闭文件。 func appendLine(path, text string) error { // | 是按位或:把多个打开标志组合起来。 file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) if err != nil { return err } _, writeErr := file.WriteString(text + "\n") closeErr := file.Close() // 即使写入失败,也必须尝试关闭。 if writeErr != nil { return writeErr } return closeErr } // readLines 使用 Scanner 逐行读取,并演示 defer 关闭只读文件。 func readLines(path string) ([]string, error) { file, err := os.Open(path) if err != nil { return nil, err } // 本例只读文件,不依赖 Close 完成写入,因此简化为忽略关闭错误。 defer file.Close() var lines []string scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) } // Scan 返回 false,既可能是正常结束,也可能是读取失败。 if err := scanner.Err(); err != nil { return nil, err } return lines, nil } func run() error { // 1. 每次创建独立临时目录,不覆盖已有文件。 // 示例保留目录供你查看,不执行自动删除。 directory, err := os.MkdirTemp("", "go-lesson17-") if err != nil { return err } fmt.Println("示例目录(运行后保留):", directory) // 2. Join 按当前系统规则拼接路径,避免手工拼反斜杠。 path := filepath.Join(directory, "notes.txt") fmt.Printf("文件名:%s,扩展名:%s\n", filepath.Base(path), filepath.Ext(path)) // 3. WriteFile 写入全部内容;已有文件会被截断并覆盖,务必确认路径。 content := "第17课:文件读写\n复习 defer\n" if err := os.WriteFile(path, []byte(content), 0600); err != nil { return err } // 4. ReadFile 返回 []byte,转成 string 后按文本显示。 data, err := os.ReadFile(path) if err != nil { return err } fmt.Println("=== 整体读取 ===") fmt.Print(string(data)) // 5. 追加不会清空已有内容。 if err := appendLine(path, "学习逐行读取"); err != nil { return err } lines, err := readLines(path) if err != nil { return err } fmt.Println("=== 追加后逐行读取 ===") for index, line := range lines { fmt.Printf("第 %d 行:%s\n", index+1, line) } // 6. Stat 获取信息。Size 是字节数,不是中文字符数。 info, err := os.Stat(path) if err != nil { return err } fmt.Printf("文件名:%s,是否目录:%t,行数:%d\n", info.Name(), info.IsDir(), len(lines)) return nil } func main() { if err := run(); err != nil { fmt.Fprintln(os.Stderr, "文件操作失败:", err) // run 已返回,其内部的 defer 已执行;这里才退出进程。 os.Exit(1) } }