godoos/godo/files/os.go
2024-08-01 17:27:02 +08:00

257 lines
6.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package files
import (
"fmt"
"godo/libs"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
"time"
)
// Common response structure
type OsFileInfo struct {
IsFile bool `json:"isFile"`
IsDir bool `json:"isDirectory"`
IsSymlink bool `json:"isSymlink"`
Size int64 `json:"size"`
ModTime time.Time `json:"modTime"`
AccessTime time.Time `json:"atime"`
CreateTime time.Time `json:"birthtime"`
Mode os.FileMode `json:"mode"`
Name string `json:"name"` // 文件名
Path string `json:"path"` // 文件路径
OldPath string `json:"oldPath"` // 旧的文件路径
ParentPath string `json:"parentPath"` // 父目录路径
Content string `json:"content"` // 文件内容
Ext string `json:"ext"` // 文件扩展名
Title string `json:"title"` // 文件名(不包含扩展名)
ID int `json:"id,omitempty"` // 文件ID可选
}
// validateFilePath 验证路径不为空
func validateFilePath(path string) error {
if path == "" {
return fmt.Errorf("empty path")
}
return nil
}
// validateFilePathPair 验证源路径和目标路径不为空
func validateFilePathPair(src, dst string) error {
if err := validateFilePath(src); err != nil {
return err
}
if err := validateFilePath(dst); err != nil {
return err
}
return nil
}
// ReadDir reads a directory and returns a list of files
func ReadDir(basePath, path string) ([]os.DirEntry, error) {
fullPath := filepath.Join(basePath, path)
return os.ReadDir(fullPath)
}
// Stat retrieves file information
func Stat(basePath, path string) (os.FileInfo, error) {
fullPath := filepath.Join(basePath, path)
return os.Stat(fullPath)
}
// Exists checks if a file or directory exists
func Exists(basePath, path string) bool {
fullPath := filepath.Join(basePath, path)
// _, err := os.Stat(fullPath)
// return err == nil
return libs.PathExists(fullPath)
}
// ReadFile reads a file's content
func ReadFile(basePath, path string) ([]byte, error) {
fullPath := filepath.Join(basePath, path)
return os.ReadFile(fullPath)
}
// Unlink removes a file
func Unlink(basePath, path string) error {
fullPath := filepath.Join(basePath, path)
return os.Remove(fullPath)
}
// Clear removes the entire filesystem
func Clear(basePath string) error {
return os.RemoveAll(basePath)
}
// Rename renames a file
func Rename(basePath, oldPath, newPath string) error {
return os.Rename(filepath.Join(basePath, oldPath), filepath.Join(basePath, newPath))
}
// Mkdir creates a directory
func Mkdir(basePath, dirPath string) error {
fullPath := filepath.Join(basePath, dirPath)
return os.MkdirAll(fullPath, 0755)
}
// Rmdir removes a directory
func Rmdir(basePath, dirPath string) error {
fullPath := filepath.Join(basePath, dirPath)
return os.RemoveAll(fullPath)
}
func CopyResource(src, dst string) error {
// 检查源路径是否为目录或文件
info, err := os.Stat(src)
if err != nil {
return err
}
// 如果源路径是一个目录,则递归复制整个目录
if info.IsDir() {
return CopyDirectory(src, dst)
}
// 如果源路径是一个文件,则直接复制文件
return CopyFile(src, dst)
}
func CopyDirectory(src, dst string) error {
// 创建目标目录
if err := os.MkdirAll(dst, os.ModePerm); err != nil {
return err
}
// 遍历源目录中的所有文件和子目录
files, err := os.ReadDir(src)
if err != nil {
return err
}
for _, file := range files {
// 构建源文件和目标文件的完整路径
srcPath := filepath.Join(src, file.Name())
dstPath := filepath.Join(dst, file.Name())
// 递归复制子目录或复制文件
if file.IsDir() {
if err := CopyDirectory(srcPath, dstPath); err != nil {
return err
}
} else {
if err := CopyFile(srcPath, dstPath); err != nil {
return err
}
}
}
return nil
}
// CopyFile copies a file
func CopyFile(src, dst string) error {
sf, err := os.Open(src)
if err != nil {
return err
}
defer sf.Close()
df, err := os.Create(dst)
if err != nil {
return err
}
defer df.Close()
_, err = io.Copy(df, sf)
if err != nil {
return err
}
err = df.Sync()
if err != nil {
return err
}
return df.Close()
}
// WriteFile writes content to a file
func WriteFile(filePath string, content []byte, perm os.FileMode) error {
return os.WriteFile(filePath, content, perm)
}
// AppendToFile appends content to a file
// AppendToFile appends the given content to the specified file.
// It assumes that 'content' is an io.Reader representing the data to append.
func AppendToFile(filePath string, content io.Reader) error {
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
// 文件不存在或打开时发生其他错误
return err
}
defer file.Close()
// 将内容写入文件
if _, err := io.Copy(file, content); err != nil {
return err
}
return nil
}
func Chmod(basePath string, path string, mode os.FileMode) error {
fullPath := filepath.Join(basePath, path)
return os.Chmod(fullPath, mode)
}
// GetFileInfo 从fs.DirEntry或路径获取文件信息
func GetFileInfo(entry interface{}, basePath, parentPath string) (*OsFileInfo, error) {
var fileInfo os.FileInfo
var err error
var filePath string
switch v := entry.(type) {
case fs.DirEntry:
// 如果传入的是fs.DirEntry
fileInfo, err = v.Info()
if err != nil {
return nil, fmt.Errorf("failed to get file info from DirEntry: %v", err)
}
filePath = filepath.Join(basePath, parentPath, fileInfo.Name())
case string:
// 如果传入的是路径字符串
filePath = filepath.Join(basePath, parentPath, v)
fileInfo, err = os.Stat(filePath)
if err != nil {
return nil, fmt.Errorf("failed to stat file from path: %v", err)
}
default:
return nil, fmt.Errorf("unsupported type provided to GetFileInfo, expected fs.DirEntry or string")
}
osFileInfo := &OsFileInfo{
Name: fileInfo.Name(),
Path: filePath, // 根据实际情况调整可能需要使用之前构造的完整路径filePath
}
// 初始化其他字段如IsFile, IsDir, Size等
osFileInfo.ID = 0
osFileInfo.IsFile = !fileInfo.IsDir()
osFileInfo.IsDir = fileInfo.IsDir()
osFileInfo.Size = fileInfo.Size()
osFileInfo.ModTime = fileInfo.ModTime()
osFileInfo.AccessTime = fileInfo.ModTime() // 注意os.FileInfo没有直接提供访问时间这里用修改时间代替
osFileInfo.CreateTime = fileInfo.ModTime() // 同上,仅作示例
osFileInfo.Mode = fileInfo.Mode()
osFileInfo.Path = strings.TrimPrefix(filePath, basePath)
osFileInfo.OldPath = osFileInfo.Path
osFileInfo.ParentPath = parentPath
osFileInfo.Title = strings.TrimSuffix(osFileInfo.Name, filepath.Ext(osFileInfo.Name))
osFileInfo.Ext = strings.TrimPrefix(filepath.Ext(osFileInfo.Name), ".")
return osFileInfo, nil
}