Private
Public Access
1
0
Files
u-desk/internal/filesystem/fs.go
2025-12-30 20:27:35 +08:00

191 lines
4.2 KiB
Go
Raw Permalink 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 filesystem
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
// ReadFile 读取文件内容
func ReadFile(path string) (string, error) {
if !isSafePath(path) {
return "", fmt.Errorf("路径不安全")
}
data, err := os.ReadFile(path)
if err != nil {
return "", fmt.Errorf("读取文件失败: %v", err)
}
return string(data), nil
}
// WriteFile 写入文件
func WriteFile(path, content string) error {
if !isSafePath(path) {
return fmt.Errorf("路径不安全")
}
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("创建目录失败: %v", err)
}
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
return fmt.Errorf("写入文件失败: %v", err)
}
return nil
}
// ListDir 列出目录内容
func ListDir(path string) ([]map[string]interface{}, error) {
if !isSafePath(path) {
return nil, fmt.Errorf("路径不安全")
}
entries, err := os.ReadDir(path)
if err != nil {
return nil, fmt.Errorf("读取目录失败: %v", err)
}
var result []map[string]interface{}
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
continue
}
fullPath := filepath.Join(path, entry.Name())
result = append(result, map[string]interface{}{
"name": entry.Name(),
"path": fullPath,
"is_dir": entry.IsDir(),
"size": info.Size(),
"mod_time": info.ModTime().Format("2006-01-02 15:04:05"),
})
}
return result, nil
}
// CreateDir 创建目录
func CreateDir(path string) error {
if !isSafePath(path) {
return fmt.Errorf("路径不安全")
}
if err := os.MkdirAll(path, 0755); err != nil {
return fmt.Errorf("创建目录失败: %v", err)
}
return nil
}
// DeletePath 删除文件或目录
func DeletePath(path string) error {
if !isSafePath(path) {
return fmt.Errorf("路径不安全")
}
info, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("文件或目录不存在")
}
return fmt.Errorf("获取文件信息失败: %v", err)
}
if info.IsDir() {
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("删除目录失败: %v", err)
}
} else {
if err := os.Remove(path); err != nil {
return fmt.Errorf("删除文件失败: %v", err)
}
}
return nil
}
// GetFileInfo 获取文件信息
func GetFileInfo(path string) (map[string]interface{}, error) {
if !isSafePath(path) {
return nil, fmt.Errorf("路径不安全")
}
info, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("文件或目录不存在")
}
return nil, fmt.Errorf("获取文件信息失败: %v", err)
}
formatBytes := func(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.2f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
return map[string]interface{}{
"name": info.Name(),
"path": path,
"size": info.Size(),
"size_str": formatBytes(info.Size()),
"is_dir": info.IsDir(),
"mod_time": info.ModTime().Format("2006-01-02 15:04:05"),
"mode": info.Mode().String(),
}, nil
}
// OpenPath 打开文件或目录(使用系统默认程序)
func OpenPath(path string) error {
if !isSafePath(path) {
return fmt.Errorf("路径不安全")
}
// 注意:这里需要导入 os/exec但为了安全暂时不实现执行命令
// 可以考虑使用 Wails 的 runtime 包提供的功能
return fmt.Errorf("打开功能暂未实现,请手动打开: %s", path)
}
// isSafePath 检查路径是否安全(防止路径遍历攻击)
func isSafePath(path string) bool {
// 清理路径
cleanPath := filepath.Clean(path)
// 检查是否包含路径遍历
if strings.Contains(cleanPath, "..") {
return false
}
// Windows 下检查是否尝试访问系统关键目录
if runtime.GOOS == "windows" {
lowerPath := strings.ToLower(cleanPath)
// 禁止访问系统关键目录(可根据需要调整)
forbidden := []string{
"c:\\windows",
"c:\\program files",
"c:\\programdata",
}
for _, fb := range forbidden {
if strings.HasPrefix(lowerPath, fb) {
return false
}
}
}
return true
}