package storage import ( "os" "path/filepath" ) type Storage interface { Stat(path string) (os.FileInfo, error) Open(path string) (*os.File, error) Create(path string) (*os.File, error) Remove(path string) error Rename(oldPath, newPath string) error MkdirAll(path string) error List(path string) ([]os.FileInfo, error) } type Local struct{ Root string } func (s Local) real(path string) string { return filepath.Join(s.Root, filepath.Clean("/"+path)) } func (s Local) Stat(path string) (os.FileInfo, error) { return os.Stat(s.real(path)) } func (s Local) Open(path string) (*os.File, error) { return os.Open(s.real(path)) } func (s Local) Create(path string) (*os.File, error) { p := s.real(path) if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil { return nil, err } return os.Create(p) } func (s Local) Remove(path string) error { return os.RemoveAll(s.real(path)) } func (s Local) Rename(a, b string) error { return os.Rename(s.real(a), s.real(b)) } func (s Local) MkdirAll(path string) error { return os.MkdirAll(s.real(path), 0755) } func (s Local) List(path string) ([]os.FileInfo, error) { f, err := os.Open(s.real(path)) if err != nil { return nil, err } defer f.Close() return f.Readdir(-1) }