Add configuration information file storage

This commit is contained in:
2025-04-27 18:04:08 +08:00
parent 946075f25d
commit 3ab209f899
20 changed files with 1106 additions and 58 deletions

View File

@@ -0,0 +1,146 @@
package services
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"sync"
)
// FileService 提供原子化文件操作
type FileService struct {
mutex sync.Mutex
}
// NewFileService 创建新的文件服务实例
func NewFileService() *FileService {
return &FileService{}
}
// EnsureDir 确保目录存在,如不存在则创建
func (fs *FileService) EnsureDir(dirPath string) error {
fs.mutex.Lock()
defer fs.mutex.Unlock()
return fs.ensureDirNoLock(dirPath)
}
// ensureDirNoLock 无锁版本的EnsureDir仅供内部使用
func (fs *FileService) ensureDirNoLock(dirPath string) error {
log.Printf("EnsureDir: Checking directory: %s", dirPath)
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
log.Printf("EnsureDir: Directory does not exist, creating: %s", dirPath)
err := os.MkdirAll(dirPath, 0755)
if err != nil {
log.Printf("EnsureDir: Failed to create directory: %v", err)
return err
}
log.Printf("EnsureDir: Directory created successfully: %s", dirPath)
} else {
log.Printf("EnsureDir: Directory already exists: %s", dirPath)
}
return nil
}
// SaveJSON 原子化保存JSON数据到文件
func (fs *FileService) SaveJSON(filePath string, data interface{}) error {
fs.mutex.Lock()
defer fs.mutex.Unlock()
log.Printf("SaveJSON: Saving to file: %s", filePath)
// 确保目录存在 - 使用无锁版本以避免死锁
dir := filepath.Dir(filePath)
if err := fs.ensureDirNoLock(dir); err != nil {
log.Printf("SaveJSON: Failed to create directory: %v", err)
return fmt.Errorf("failed to create directory: %w", err)
}
// 将数据编码为JSON
jsonData, err := json.MarshalIndent(data, "", " ")
if err != nil {
log.Printf("SaveJSON: Failed to encode JSON: %v", err)
return fmt.Errorf("failed to encode JSON: %w", err)
}
// 先写入临时文件
tempFile := filePath + ".tmp"
log.Printf("SaveJSON: Writing to temporary file: %s", tempFile)
if err := os.WriteFile(tempFile, jsonData, 0644); err != nil {
log.Printf("SaveJSON: Failed to write temporary file: %v", err)
return fmt.Errorf("failed to write temporary file: %w", err)
}
// 原子替换原文件
log.Printf("SaveJSON: Replacing original file with temporary file")
if err := os.Rename(tempFile, filePath); err != nil {
os.Remove(tempFile) // 清理临时文件
log.Printf("SaveJSON: Failed to replace file: %v", err)
return fmt.Errorf("failed to replace file: %w", err)
}
log.Printf("SaveJSON: File saved successfully: %s", filePath)
return nil
}
// LoadJSON 从文件加载JSON数据
func (fs *FileService) LoadJSON(filePath string, target interface{}) error {
fs.mutex.Lock()
defer fs.mutex.Unlock()
log.Printf("LoadJSON: Loading from file: %s", filePath)
// 检查文件是否存在
if _, err := os.Stat(filePath); os.IsNotExist(err) {
log.Printf("LoadJSON: File does not exist: %s", filePath)
return fmt.Errorf("file does not exist: %w", err)
}
// 读取文件内容
data, err := os.ReadFile(filePath)
if err != nil {
log.Printf("LoadJSON: Failed to read file: %v", err)
return fmt.Errorf("failed to read file: %w", err)
}
// 解析JSON数据
if err := json.Unmarshal(data, target); err != nil {
log.Printf("LoadJSON: Failed to parse JSON: %v", err)
return fmt.Errorf("failed to parse JSON: %w", err)
}
log.Printf("LoadJSON: File loaded successfully: %s", filePath)
return nil
}
// FileExists 检查文件是否存在
func (fs *FileService) FileExists(filePath string) bool {
_, err := os.Stat(filePath)
exists := !os.IsNotExist(err)
log.Printf("FileExists: Checking if file exists: %s, exists: %v", filePath, exists)
return exists
}
// DeleteFile 删除文件
func (fs *FileService) DeleteFile(filePath string) error {
fs.mutex.Lock()
defer fs.mutex.Unlock()
log.Printf("DeleteFile: Deleting file: %s", filePath)
if !fs.FileExists(filePath) {
log.Printf("DeleteFile: File does not exist, nothing to delete: %s", filePath)
return nil // 文件不存在视为删除成功
}
err := os.Remove(filePath)
if err != nil {
log.Printf("DeleteFile: Failed to delete file: %v", err)
} else {
log.Printf("DeleteFile: File deleted successfully: %s", filePath)
}
return err
}