Files
gf/os/gres/gres_fs_std.go

154 lines
3.0 KiB
Go
Raw Normal View History

2024-12-09 22:35:40 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gres
import (
"io"
"io/fs"
"os"
"path/filepath"
"github.com/gogf/gf/v2/errors/gerror"
)
// StdFS implements the FS interface using the standard library fs.FS.
type StdFS struct {
fs fs.FS
}
2024-12-09 23:43:29 +08:00
var _ FS = (*StdFS)(nil)
2024-12-09 22:35:40 +08:00
// NewStdFS creates and returns a new StdFS.
func NewStdFS(fs fs.FS) *StdFS {
return &StdFS{
fs: fs,
}
}
// Get returns the file with given path.
2024-12-09 23:43:29 +08:00
func (fs *StdFS) Get(path string) File {
2024-12-09 22:35:40 +08:00
f, err := fs.fs.Open(path)
if err != nil {
return nil
}
defer f.Close()
info, err := f.Stat()
if err != nil {
2024-12-09 23:43:29 +08:00
panic(err)
2024-12-09 22:35:40 +08:00
return nil
}
// Read the content
content, err := io.ReadAll(f)
if err != nil {
return nil
}
2024-12-09 23:43:29 +08:00
file := &localFile{
name: info.Name(),
path: path,
file: info,
content: content,
fs: fs,
2024-12-09 22:35:40 +08:00
}
return file
}
// IsEmpty checks and returns whether the resource is empty.
func (fs *StdFS) IsEmpty() bool {
if dir, ok := fs.fs.(interface {
ReadDir(name string) ([]os.DirEntry, error)
}); ok {
entries, err := dir.ReadDir(".")
if err != nil {
return true
}
return len(entries) == 0
}
return true
}
// ScanDir returns the files under the given path,
// the parameter `path` should be a folder type.
2024-12-09 23:43:29 +08:00
func (fs *StdFS) ScanDir(path string, pattern string, recursive ...bool) []File {
2024-12-09 22:35:40 +08:00
var (
2024-12-09 23:43:29 +08:00
files = make([]File, 0)
2024-12-09 22:35:40 +08:00
isRecursive = len(recursive) > 0 && recursive[0]
)
err := fs.walkDir(path, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if !d.IsDir() {
matched, err := filepath.Match(pattern, filepath.Base(path))
if err != nil {
return err
}
if matched {
if file := fs.Get(path); file != nil {
files = append(files, file)
}
}
}
if !isRecursive && d.IsDir() && path != "." {
return filepath.SkipDir
}
return nil
})
if err != nil {
return nil
}
return files
}
// walkDir walks the file tree rooted at path, calling fn for each file or
// directory in the tree, including path.
func (fs *StdFS) walkDir(path string, fn func(path string, d os.DirEntry, err error) error) error {
if dir, ok := fs.fs.(interface {
ReadDir(name string) ([]os.DirEntry, error)
}); ok {
entries, err := dir.ReadDir(path)
if err != nil {
err = fn(path, nil, err)
if err != nil {
return err
}
return nil
}
for _, entry := range entries {
var (
fileName = entry.Name()
filePath = filepath.Join(path, fileName)
)
err = fn(filePath, entry, nil)
if err != nil {
if gerror.Is(err, filepath.SkipDir) {
if entry.IsDir() {
continue
}
return nil
}
return err
}
if entry.IsDir() {
err = fs.walkDir(filePath, fn)
if err != nil {
if gerror.Is(err, filepath.SkipDir) {
continue
}
return err
}
}
}
return nil
}
return gerror.New("filesystem does not implement ReadDir")
}