Files
SeeyonFileSystem/server/storage/local.go
2026-07-03 15:58:29 +08:00

114 lines
3.0 KiB
Go

package storage
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
)
// LocalEngine 本地磁盘存储引擎
type LocalEngine struct {
BasePath string // 存储根目录
CDNHost string // CDN地址, 如 http://localhost:3090
CDNPathPrefix string // CDN路径前缀, 如 /public
}
// NewLocalEngine 创建本地存储引擎实例
func NewLocalEngine(basePath string) *LocalEngine {
os.MkdirAll(basePath, 0755)
return &LocalEngine{BasePath: basePath}
}
// NewLocalEngineWithCDN 创建带CDN配置的本地存储引擎
func NewLocalEngineWithCDN(basePath, cdnHost, cdnPathPrefix string) *LocalEngine {
os.MkdirAll(basePath, 0755)
return &LocalEngine{
BasePath: basePath,
CDNHost: cdnHost,
CDNPathPrefix: cdnPathPrefix,
}
}
// Upload 上传文件到本地磁盘
func (e *LocalEngine) Upload(storageKey string, reader io.Reader, size int64) error {
fullPath := filepath.Join(e.BasePath, storageKey)
dir := filepath.Dir(fullPath)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("创建目录失败: %w", err)
}
dst, err := os.Create(fullPath)
if err != nil {
return fmt.Errorf("创建文件失败: %w", err)
}
defer dst.Close()
if _, err := io.Copy(dst, reader); err != nil {
os.Remove(fullPath)
return fmt.Errorf("写入文件失败: %w", err)
}
return nil
}
// Download 从本地磁盘下载文件
func (e *LocalEngine) Download(storageKey string) (io.ReadCloser, error) {
fullPath := filepath.Join(e.BasePath, storageKey)
file, err := os.Open(fullPath)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("文件不存在: %s", storageKey)
}
return nil, fmt.Errorf("打开文件失败: %w", err)
}
return file, nil
}
// Delete 从本地磁盘删除文件
func (e *LocalEngine) Delete(storageKey string) error {
fullPath := filepath.Join(e.BasePath, storageKey)
err := os.Remove(fullPath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("删除文件失败: %w", err)
}
return nil
}
// Exists 判断文件是否存在于本地磁盘
func (e *LocalEngine) Exists(storageKey string) (bool, error) {
fullPath := filepath.Join(e.BasePath, storageKey)
_, err := os.Stat(fullPath)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// GetURL 获取文件访问URL
// 配置了CDN: http://localhost:3090/public/2026/07/02/ab/xxx.txt
// 未配置CDN: /storage/2026/07/02/ab/xxx.txt
func (e *LocalEngine) GetURL(storageKey string) string {
if e.CDNHost != "" {
// 确保路径格式正确
prefix := strings.TrimRight(e.CDNPathPrefix, "/")
key := strings.TrimLeft(storageKey, "/")
return fmt.Sprintf("%s%s/%s", e.CDNHost, prefix, key)
}
return "/storage/" + storageKey
}
// GenerateStorageKey 生成存储路径
func GenerateStorageKey(md5, extension string) string {
now := time.Now()
day := now.Format("2006/01/02")
if extension != "" {
return fmt.Sprintf("%s/%s/%s.%s", day, md5[:2], md5, extension)
}
return fmt.Sprintf("%s/%s/%s", day, md5[:2], md5)
}