Go语言的文件操作进阶
文件操作基础
Go语言提供了强大的文件操作功能,包括文件读写、目录操作、文件权限管理等。本文将介绍Go语言文件操作的进阶概念和技巧,帮助开发者编写更复杂、更高效的文件处理程序。
文件读写
基本文件读取
package main import ( "fmt" "io/ioutil" "os" ) func main() { // 读取整个文件 content, err := ioutil.ReadFile("example.txt") if err != nil { fmt.Println("Error reading file:", err) return } fmt.Println("File content:", string(content)) }基本文件写入
package main import ( "fmt" "io/ioutil" ) func main() { // 写入文件 content := []byte("Hello, Go file operations!") err := ioutil.WriteFile("example.txt", content, 0644) if err != nil { fmt.Println("Error writing file:", err) return } fmt.Println("File written successfully") }高级文件操作
按行读取文件
package main import ( "bufio" "fmt" "os" ) func main() { file, err := os.Open("example.txt") if err != nil { fmt.Println("Error opening file:", err) return } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Println("Error scanning file:", err) } }带缓冲的文件读写
package main import ( "bufio" "fmt" "os" ) func main() { // 写入文件 file, err := os.Create("example.txt") if err != nil { fmt.Println("Error creating file:", err) return } defer file.Close() writer := bufio.NewWriter(file) writer.WriteString("Hello, ") writer.WriteString("Go file operations!") writer.Flush() // 确保所有数据都被写入 // 读取文件 file, err = os.Open("example.txt") if err != nil { fmt.Println("Error opening file:", err) return } defer file.Close() reader := bufio.NewReader(file) content, err := reader.ReadString('!') if err != nil { fmt.Println("Error reading file:", err) return } fmt.Println("File content:", content) }目录操作
创建目录
package main import ( "fmt" "os" ) func main() { // 创建单个目录 err := os.Mkdir("mydir", 0755) if err != nil { fmt.Println("Error creating directory:", err) return } fmt.Println("Directory created successfully") // 创建多级目录 err = os.MkdirAll("mydir/subdir1/subdir2", 0755) if err != nil { fmt.Println("Error creating nested directories:", err) return } fmt.Println("Nested directories created successfully") }列出目录内容
package main import ( "fmt" "os" ) func main() { // 列出目录内容 entries, err := os.ReadDir(".") if err != nil { fmt.Println("Error reading directory:", err) return } fmt.Println("Directory entries:") for _, entry := range entries { if entry.IsDir() { fmt.Printf("[DIR] %s\n", entry.Name()) } else { fmt.Printf("[FILE] %s\n", entry.Name()) } } }文件信息和权限
获取文件信息
package main import ( "fmt" "os" "time" ) func main() { info, err := os.Stat("example.txt") if err != nil { fmt.Println("Error getting file info:", err) return } fmt.Printf("Name: %s\n", info.Name()) fmt.Printf("Size: %d bytes\n", info.Size()) fmt.Printf("Mode: %v\n", info.Mode()) fmt.Printf("ModTime: %v\n", info.ModTime()) fmt.Printf("IsDir: %t\n", info.IsDir()) }修改文件权限
package main import ( "fmt" "os" ) func main() { // 修改文件权限 err := os.Chmod("example.txt", 0600) if err != nil { fmt.Println("Error changing file permissions:", err) return } fmt.Println("File permissions changed successfully") // 查看修改后的权限 info, err := os.Stat("example.txt") if err != nil { fmt.Println("Error getting file info:", err) return } fmt.Printf("New permissions: %v\n", info.Mode()) }文件系统操作
文件重命名和移动
package main import ( "fmt" "os" ) func main() { // 重命名文件 err := os.Rename("oldname.txt", "newname.txt") if err != nil { fmt.Println("Error renaming file:", err) return } fmt.Println("File renamed successfully") // 移动文件到另一个目录 err = os.Rename("newname.txt", "mydir/newname.txt") if err != nil { fmt.Println("Error moving file:", err) return } fmt.Println("File moved successfully") }文件复制
package main import ( "fmt" "io" "os" ) func copyFile(src, dst string) error { source, err := os.Open(src) if err != nil { return err } defer source.Close() destination, err := os.Create(dst) if err != nil { return err } defer destination.Close() _, err = io.Copy(destination, source) return err } func main() { err := copyFile("example.txt", "example_copy.txt") if err != nil { fmt.Println("Error copying file:", err) return } fmt.Println("File copied successfully") }临时文件和目录
创建临时文件
package main import ( "fmt" "os" ) func main() { // 创建临时文件 file, err := os.CreateTemp(".", "temp-") if err != nil { fmt.Println("Error creating temp file:", err) return } defer os.Remove(file.Name()) // 清理临时文件 defer file.Close() // 写入数据 file.WriteString("Temporary data") fmt.Printf("Created temp file: %s\n", file.Name()) }创建临时目录
package main import ( "fmt" "os" "path/filepath" ) func main() { // 创建临时目录 dir, err := os.MkdirTemp(".", "tempdir-") if err != nil { fmt.Println("Error creating temp directory:", err) return } defer os.RemoveAll(dir) // 清理临时目录 // 在临时目录中创建文件 filePath := filepath.Join(dir, "tempfile.txt") err = os.WriteFile(filePath, []byte("Temporary file in temp directory"), 0644) if err != nil { fmt.Println("Error writing to temp file:", err) return } fmt.Printf("Created temp directory: %s\n", dir) fmt.Printf("Created temp file: %s\n", filePath) }示例:文件系统walker
package main import ( "fmt" "os" "path/filepath" ) func walkFunc(path string, info os.FileInfo, err error) error { if err != nil { fmt.Println("Error accessing path:", err) return nil } depth := len(filepath.SplitList(path)) - 1 indent := "" for i := 0; i < depth; i++ { indent += " " } if info.IsDir() { fmt.Printf("%s[DIR] %s\n", indent, info.Name()) } else { fmt.Printf("%s[FILE] %s (%.2f KB)\n", indent, info.Name(), float64(info.Size())/1024) } return nil } func main() { err := filepath.Walk(".", walkFunc) if err != nil { fmt.Println("Error walking directory:", err) return } }示例:文件压缩和解压缩
压缩文件
package main import ( "fmt" "os" "path/filepath" "archive/zip" ) func zipDirectory(source, target string) error { // 创建zip文件 zipFile, err := os.Create(target) if err != nil { return err } defer zipFile.Close() // 创建zip writer zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close() // 遍历目录 return filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err } // 跳过目录 if info.IsDir() { return nil } // 创建相对路径 relPath, err := filepath.Rel(source, path) if err != nil { return err } // 创建zip文件条目 zipEntry, err := zipWriter.Create(relPath) if err != nil { return err } // 读取源文件 sourceFile, err := os.Open(path) if err != nil { return err } defer sourceFile.Close() // 复制到zip文件 _, err = io.Copy(zipEntry, sourceFile) return err }) } func main() { err := zipDirectory("./mydir", "archive.zip") if err != nil { fmt.Println("Error creating zip archive:", err) return } fmt.Println("Zip archive created successfully") }解压缩文件
package main import ( "fmt" "io" "os" "path/filepath" "archive/zip" ) func unzipArchive(archive, target string) error { // 打开zip文件 zipReader, err := zip.OpenReader(archive) if err != nil { return err } defer zipReader.Close() // 确保目标目录存在 err = os.MkdirAll(target, 0755) if err != nil { return err } // 遍历zip文件条目 for _, file := range zipReader.File { // 创建目标文件路径 destPath := filepath.Join(target, file.Name) // 创建目录结构 err = os.MkdirAll(filepath.Dir(destPath), 0755) if err != nil { return err } // 打开zip条目 src, err := file.Open() if err != nil { return err } // 创建目标文件 dst, err := os.Create(destPath) if err != nil { src.Close() return err } // 复制内容 _, err = io.Copy(dst, src) src.Close() dst.Close() if err != nil { return err } // 设置权限 err = os.Chmod(destPath, file.Mode()) if err != nil { return err } } return nil } func main() { err := unzipArchive("archive.zip", "./unzipped") if err != nil { fmt.Println("Error extracting zip archive:", err) return } fmt.Println("Zip archive extracted successfully") }文件操作最佳实践
- 总是使用
defer关闭文件 - 处理所有可能的错误
- 使用缓冲I/O提高性能
- 对于大文件,使用分块读取
- 合理设置文件权限
- 清理临时文件和目录
- 使用
filepath包处理路径
总结
Go语言的文件操作功能强大且灵活,通过掌握高级文件操作技巧,可以编写更加高效、可靠的文件处理程序。在实际开发中,应该根据具体场景选择合适的文件操作方法,确保代码的可读性和性能。