
文件操作
写入文件
追加
go
package main
import (
"fmt"
"os"
)
func WriteFileAppend(path string) {
// 使用 os.OpenFile 并指定追加模式
// os.O_APPEND 表示追加写入
// os.O_CREATE 表示如果文件不存在则创建
// os.O_WRONLY 表示只写模式
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("err =", err)
return
}
defer f.Close()
// 开始追加写入
for i := 0; i < 10; i++ {
buf := fmt.Sprintf("追加内容 i = %d\n", i)
n, err := f.WriteString(buf)
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Printf("追加写入字节数: %d\n", n)
}
fmt.Println("文件已追加写入完成")
}
func main() {
WriteFileAppend("test.txt")
}
覆盖
go
package main
import (
"fmt"
"os"
)
func WriteFileOverwrite(path string) {
// 使用 os.Create 会清空文件内容(如果文件已存在)
f, err := os.Create(path)
if err != nil {
fmt.Println("err =", err)
return
}
defer f.Close()
// 开始写入
for i := 0; i < 10; i++ {
buf := fmt.Sprintf("i = %d\n", i)
n, err := f.WriteString(buf)
if err != nil {
fmt.Println("err =", err)
return
}
fmt.Printf("写入字节数: %d\n", n)
}
fmt.Println("文件已覆盖写入完成")
}
func main() {
WriteFileOverwrite("test.txt")
}
读取
固定字节读取
go
package main
import (
"fmt"
"io"
"os"
)
func ReadFile(path string) error {
// 打开文件
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("打开文件错误: %v", err)
}
defer f.Close()
// 使用缓冲区逐块读取文件
buf := make([]byte, 32*1024) // 32KB缓冲区
var totalRead int
var content []byte
for {
n, err := f.Read(buf)
if n > 0 {
totalRead += n
// 将读取的数据追加到内容切片中
content = append(content, buf[:n]...)
}
if err != nil {
if err == io.EOF {
break // 正常结束
}
return fmt.Errorf("读取错误: %v", err)
}
}
fmt.Printf("文件大小: %d 字节\n", totalRead)
fmt.Println("文件内容:")
fmt.Println(string(content))
return nil
}
func main() {
// 创建示例文件
content := ""
// 创建一个较大的文件内容示例
for i := 0; i < 100; i++ {
content += fmt.Sprintf("这是第%d行内容\n", i+3)
}
err := os.WriteFile("example.txt", []byte(content), 0644)
if err != nil {
fmt.Println("创建文件错误:", err)
return
}
defer os.Remove("example.txt") // 程序结束时清理文件
fmt.Println("=== 使用ReadFile函数 ===")
if err := ReadFile("example.txt"); err != nil {
fmt.Println("错误:", err)
}
}
整行读取-高效写法
go
package main
import (
"bufio"
"fmt"
"io"
"os"
)
// 更高效的版本 - 使用bufio.Scanner逐行读取
func ReadFileEfficient(path string) error {
// 打开文件
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("打开文件错误: %v", err)
}
defer f.Close()
fmt.Println("文件内容(逐行读取):")
scanner := bufio.NewScanner(f)
lineNum := 1
for scanner.Scan() {
fmt.Printf("%d: %s\n", lineNum, scanner.Text())
lineNum++
}
if err := scanner.Err(); err != nil {
return fmt.Errorf("扫描错误: %v", err)
}
return nil
}
func main() {
// 创建示例文件
content := ""
// 创建一个较大的文件内容示例
for i := 0; i < 100; i++ {
content += fmt.Sprintf("这是第%d行内容\n", i+3)
}
err := os.WriteFile("example.txt", []byte(content), 0644)
if err != nil {
fmt.Println("创建文件错误:", err)
return
}
defer os.Remove("example.txt") // 程序结束时清理文件
fmt.Println("\n=== 使用ReadFileEfficient函数 ===")
if err := ReadFileEfficient("example.txt"); err != nil {
fmt.Println("错误:", err)
}
}
整行读取-原始写法
go
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func ReadLine(path string) {
// 打开文件
f, err := os.Open(path)
if err != nil {
fmt.Println("打开文件错误:", err)
return
}
// 关闭文件
defer f.Close()
// 新建一个缓冲区
r := bufio.NewReader(f)
line := 1
for {
buf, err := r.ReadBytes('\n')
// 先处理读取到的数据,即使有错误也可能有部分数据
if len(buf) > 0 {
fmt.Printf("%d\t%s", line, string(buf))
line++
}
// 再检查错误
if err != nil {
if err == io.EOF {
break
}
fmt.Println("读取错误:", err)
break
}
}
}
func main() {
path := "./1.txt"
ReadLine(path)
}
删除文件
go
defer os.Remove("example.txt") // 程序结束时清理文件
判断文件是否存在
go
srcFileName := "1.txt"
// 检查源文件是否存在
if _, err := os.Stat(srcFileName); os.IsNotExist(err) {
fmt.Printf("错误: 源文件 '%s' 不存在\n", srcFileName)
return
}
文件拷贝
go
package main
import (
"fmt"
"io"
"os"
)
func main() {
srcFileName := "1.txt"
dstFileName := "2.txt"
// 检查源文件是否存在
if _, err := os.Stat(srcFileName); os.IsNotExist(err) {
fmt.Printf("错误: 源文件 '%s' 不存在\n", srcFileName)
return
}
// 以只读方式打开源文件
srcFile, err := os.Open(srcFileName)
if err != nil {
fmt.Printf("错误: 无法打开源文件 '%s': %v\n", srcFileName, err)
return
}
defer srcFile.Close() // 确保函数退出时关闭文件
// 检查目标文件是否已存在
if _, err := os.Stat(dstFileName); err == nil {
fmt.Printf("警告: 目标文件 '%s' 已存在,将被覆盖\n", dstFileName)
}
// 创建目标文件
dstFile, err := os.Create(dstFileName)
if err != nil {
fmt.Printf("错误: 无法创建目标文件 '%s': %v\n", dstFileName, err)
return
}
defer dstFile.Close() // 确保函数退出时关闭文件
// 使用缓冲区复制文件内容
buffer := make([]byte, 32*1024) // 使用32KB缓冲区
var totalBytes int64
for {
// 从源文件读取数据到缓冲区
bytesRead, readErr := srcFile.Read(buffer)
if readErr != nil && readErr != io.EOF {
fmt.Printf("错误: 读取文件时发生错误: %v\n", readErr)
return
}
// 如果读取到数据,则写入目标文件
if bytesRead > 0 {
bytesWritten, writeErr := dstFile.Write(buffer[:bytesRead])
if writeErr != nil {
fmt.Printf("错误: 写入文件时发生错误: %v\n", writeErr)
return
}
// 检查是否所有数据都已写入
if bytesWritten != bytesRead {
fmt.Printf("错误: 写入不完整: 读取了 %d 字节,但只写入了 %d 字节\n",
bytesRead, bytesWritten)
return
}
totalBytes += int64(bytesWritten)
}
// 如果到达文件末尾,退出循环
if readErr == io.EOF {
break
}
}
// 确保所有数据都已刷新到磁盘
if err := dstFile.Sync(); err != nil {
fmt.Printf("警告: 无法同步文件到磁盘: %v\n", err)
}
fmt.Printf("成功复制文件: 从 '%s' 到 '%s' (%d 字节)\n",
srcFileName, dstFileName, totalBytes)
}