zfile
是一个文件操作库,提供了文件管理、路径操作、压缩解压、内存文件、文件锁等功能。本模块设计用于简化文件系统操作,提供跨平台的统一接口。
功能概览
- 文件操作 (File Operations): 文件读写、复制、移动、删除等基本操作
- 路径管理 (Path Management): 路径解析、验证、安全路径等
- 压缩解压 (Compression): 支持 tar.gz 和 zip 格式
- 内存文件 (Memory File): 内存中的文件实现,支持自动刷新
- 文件锁 (File Lock): 跨进程文件锁,支持并发控制
- 文件句柄 (File Handle): 高级文件操作接口
安装
go get -u github.com/sohaha/zfile
导入
import "github.com/sohaha/zfile"
核心组件
1. 文件操作 (File Operations)
路径检查
// PathExist 检查路径是否存在,返回类型标识
func PathExist(path string) (int, error)
// 返回值: 1=目录, 2=文件, 3=符号链接, 0=不存在
// DirExist 检查目录是否存在
func DirExist(path string) bool
// FileExist 检查文件是否存在
func FileExist(path string) bool
文件信息
// FileSize 返回文件大小的格式化字符串
func FileSize(file string) (size string)
// FileSizeUint 返回文件大小的字节数
func FileSizeUint(file string) (size uint64)
// SizeFormat 将字节数转换为人类可读格式
func SizeFormat(s uint64) string
// GetMimeType 获取文件的MIME类型
func GetMimeType(filename string, content []byte) (ctype string)
路径操作
// RootPath 返回当前工作目录的绝对路径
func RootPath() string
// TmpPath 返回临时目录路径
func TmpPath(pattern ...string) string
// SafePath 返回相对于基础目录的安全路径
func SafePath(path string, pathRange ...string) string
// RealPath 将相对路径转换为绝对路径
func RealPath(path string, addSlash ...bool) (realPath string)
// RealPathMkdir 转换路径并创建目录
func RealPathMkdir(path string, addSlash ...bool) string
// IsSubPath 检查是否为子路径
func IsSubPath(subPath, path string) bool
// ExecutablePath 返回当前可执行文件的路径
func ExecutablePath() string
// ProgramPath 返回程序所在目录
func ProgramPath(addSlash ...bool) (path string)
文件操作
// CopyFile 复制文件
func CopyFile(source string, dest string) (err error)
// MoveFile 移动文件(跨平台)
func MoveFile(source string, dest string, force ...bool) error
// Remove 删除文件或空目录
func Remove(path string) error
// Rmdir 递归删除目录
func Rmdir(path string, notIncludeSelf ...bool) (ok bool)
权限检查
// HasPermission 检查路径是否有指定权限
func HasPermission(path string, perm os.FileMode, noUp ...bool) bool
// HasReadWritePermission 检查是否有读写权限
func HasReadWritePermission(path string) bool
目录统计
// StatDir 统计目录大小和文件数量
func StatDir(path string, options ...DirStatOptions) (size, total uint64, err error)
// DirStatOptions 目录统计选项
type DirStatOptions struct {
MaxSize uint64 // 最大总大小(字节)
MaxTotal uint64 // 最大文件数量
}
使用示例
// 检查文件是否存在
if zfile.FileExist("config.json") {
fmt.Println("配置文件存在")
}
// 获取文件大小
size := zfile.FileSize("data.txt")
fmt.Printf("文件大小: %s\\n", size)
// 转换路径
absPath := zfile.RealPath("./config")
fmt.Printf("绝对路径: %s\\n", absPath)
// 复制文件
err := zfile.CopyFile("source.txt", "dest.txt")
if err != nil {
log.Fatal(err)
}
// 检查权限
if zfile.HasReadWritePermission("data.txt") {
fmt.Println("有读写权限")
}
// 统计目录
size, total, err := zfile.StatDir("./logs", zfile.DirStatOptions{
MaxSize: 100 * 1024 * 1024, // 100MB
MaxTotal: 1000, // 1000个文件
})
if err == nil {
fmt.Printf("目录大小: %d 字节, 文件数: %d\\n", size, total)
}
2. 文件句柄 (File Handle)
高级文件操作
// CopyDir 复制目录
func CopyDir(source string, dest string, filterFn ...func(srcFilePath, destFilePath string) bool) (err error)
// ReadFile 读取文件内容
func ReadFile(path string) ([]byte, error)
// WriteFile 写入文件内容
func WriteFile(path string, b []byte, isAppend ...bool) (err error)
// ReadLineFile 按行读取文件
func ReadLineFile(path string, handle func(line int, data []byte) error) (err error)
// PutOffset 在指定偏移量写入数据
func PutOffset(path string, b []byte, offset int64) (err error)
// PutAppend 追加数据到文件
func PutAppend(path string, b []byte) (err error)
使用示例
// 读取文件
data, err := zfile.ReadFile("config.json")
if err == nil {
fmt.Printf("文件内容: %s\\n", string(data))
}
// 写入文件
err = zfile.WriteFile("output.txt", []byte("Hello World"))
if err != nil {
log.Fatal(err)
}
// 追加内容
err = zfile.PutAppend("log.txt", []byte("新的日志记录\\n"))
// 按行读取
err = zfile.ReadLineFile("data.txt", func(line int, data []byte) error {
fmt.Printf("第%d行: %s\\n", line, string(data))
return nil
})
// 复制目录
err = zfile.CopyDir("source", "dest", func(src, dest string) bool {
// 过滤函数,返回true表示复制该文件
return !strings.HasSuffix(src, ".tmp")
})
3. 压缩解压 (Compression)
压缩功能
// GzCompress 压缩目录或文件为tar.gz
func GzCompress(currentPath, dest string) (err error)
// GzDeCompress 解压tar.gz文件
func GzDeCompress(tarFile, dest string) error
// ZipCompress 压缩目录或文件为zip
func ZipCompress(currentPath, dest string) (err error)
// ZipDeCompress 解压zip文件
func ZipDeCompress(zipFile, dest string) error
使用示例
// 压缩目录
err := zfile.GzCompress("./data", "data.tar.gz")
if err != nil {
log.Fatal(err)
}
// 解压文件
err = zfile.GzDeCompress("data.tar.gz", "./extracted")
if err != nil {
log.Fatal(err)
}
// 压缩为zip
err = zfile.ZipCompress("./docs", "docs.zip")
if err != nil {
log.Fatal(err)
}
// 解压zip
err = zfile.ZipDeCompress("docs.zip", "./unzipped")
if err != nil {
log.Fatal(err)
}
4. 内存文件 (Memory File)
内存文件类型
// MemoryFile 内存文件结构
type MemoryFile struct {
// 内部字段...
}
// MemoryFileOption 内存文件配置选项
type MemoryFileOption func(*MemoryFile)
// MemoryFileAutoFlush 设置自动刷新间隔
func MemoryFileAutoFlush(second int64) func(*MemoryFile)
// MemoryFileFlushBefore 设置刷新前回调
func MemoryFileFlushBefore(fn memoryFileFlushBefore) func(*MemoryFile)
// NewMemoryFile 创建新的内存文件
func NewMemoryFile(name string, opt ...MemoryFileOption) *MemoryFile
内存文件方法
// 基本操作
func (f *MemoryFile) SetName(name string) // 设置文件名
func (f *MemoryFile) Bytes() []byte // 获取字节内容
func (f *MemoryFile) Read(buffer []byte) (int, error) // 读取数据
func (f *MemoryFile) Write(data []byte) (int, error) // 写入数据
func (f *MemoryFile) Sync() error // 同步到磁盘
func (f *MemoryFile) Close() // 关闭文件
func (f *MemoryFile) Stat() (os.FileInfo, error) // 获取文件信息
使用示例
// 创建内存文件
memFile := zfile.NewMemoryFile("temp.txt",
zfile.MemoryFileAutoFlush(30), // 30秒自动刷新
)
// 写入数据
memFile.Write([]byte("Hello Memory File"))
// 读取数据
data := memFile.Bytes()
fmt.Printf("内容: %s\\n", string(data))
// 同步到磁盘
err := memFile.Sync()
if err != nil {
log.Fatal(err)
}
// 关闭文件
memFile.Close()
5. 文件锁 (File Lock)
文件锁类型
// FileLock 文件锁结构
type FileLock struct {
// 内部字段...
}
// NewFileLock 创建新的文件锁
func NewFileLock(path string) *FileLock
文件锁方法
// Lock 获取文件锁
func (l *FileLock) Lock() error
// Unlock 释放文件锁
func (l *FileLock) Unlock() error
// Clean 清理锁文件
func (l *FileLock) Clean() error
使用示例
// 创建文件锁
fileLock := zfile.NewFileLock("app.lock")
// 获取锁
err := fileLock.Lock()
if err != nil {
log.Fatal("无法获取锁:", err)
}
// 执行需要锁保护的操作
fmt.Println("执行受保护的操作...")
// 释放锁
err = fileLock.Unlock()
if err != nil {
log.Fatal("无法释放锁:", err)
}
// 清理锁文件
fileLock.Clean()
错误处理
var (
ErrLocked = errors.New("file is locked") // 文件已被锁定
ErrNotLocked = errors.New("file is not locked") // 文件未被锁定
)
性能特性
- 跨平台支持: 支持 Windows、Linux、macOS
使用注意事项
- 路径安全: 使用
SafePath
防止目录遍历攻击
- 权限检查: 操作前检查文件权限
- 错误处理: 始终检查文件操作的错误
- 资源清理: 及时关闭文件和释放锁
- 跨平台: 注意不同操作系统的路径分隔符
- 内存管理: 大文件操作时注意内存使用
最佳实践
- 路径处理: 使用
RealPath
确保路径正确性
- 权限管理: 使用
HasPermission
检查操作权限
示例项目
package main
import (
"fmt"
"log"
"github.com/sohaha/zfile"
)
func main() {
// 检查文件是否存在
if !zfile.FileExist("config.json") {
// 创建默认配置
err := zfile.WriteFile("config.json", []byte(`{"debug": true}`))
if err != nil {
log.Fatal(err)
}
}
// 读取配置
data, err := zfile.ReadFile("config.json")
if err != nil {
log.Fatal(err)
}
fmt.Printf("配置内容: %s\\n", string(data))
// 创建日志目录
logDir := zfile.RealPathMkdir("./logs")
fmt.Printf("日志目录: %s\\n", logDir)
// 写入日志
logFile := logDir + "/app.log"
err = zfile.PutAppend(logFile, []byte("应用启动\\n"))
if err != nil {
log.Fatal(err)
}
// 统计日志目录
size, total, err := zfile.StatDir(logDir)
if err == nil {
fmt.Printf("日志目录大小: %s, 文件数: %d\\n",
zfile.SizeFormat(size), total)
}
}