符号链接支持,可以通过mklink(Windows)或者ln -s (Linux)将其他路径下的文件夹链接到根目录下而无需将文件复制到根目录下.针对删除场景特殊处理,删除整个符号链接目录不会删除链接目录内文件,仅删除链接,在符号链接目录操作同普通目录

This commit is contained in:
wenyifan
2022-07-02 14:32:02 +08:00
parent 1ec66adda0
commit 3f38998fe5
7 changed files with 43 additions and 30 deletions

View File

@ -203,7 +203,7 @@ func (fs *memFS) walk(op, fullname string, f func(dir *memFSNode, frag string, f
Err: os.ErrNotExist,
}
}
if !child.mode.IsDir() {
if !child.mode.IsDir() && !(child.mode&os.ModeSymlink > 0) {
return &os.PathError{
Op: op,
Path: original,
@ -468,7 +468,7 @@ func (f *memFileInfo) Name() string { return f.name }
func (f *memFileInfo) Size() int64 { return f.size }
func (f *memFileInfo) Mode() os.FileMode { return f.mode }
func (f *memFileInfo) ModTime() time.Time { return f.modTime }
func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() }
func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() || (f.mode&os.ModeSymlink > 0) }
func (f *memFileInfo) Sys() interface{} { return nil }
// A memFile is a File implementation for a memFSNode. It is a per-file (not
@ -495,7 +495,7 @@ func (f *memFile) Close() error {
func (f *memFile) Read(p []byte) (int, error) {
f.n.mu.Lock()
defer f.n.mu.Unlock()
if f.n.mode.IsDir() {
if f.n.mode.IsDir() || (f.n.mode&os.ModeSymlink > 0) {
return 0, os.ErrInvalid
}
if f.pos >= len(f.n.data) {
@ -509,7 +509,7 @@ func (f *memFile) Read(p []byte) (int, error) {
func (f *memFile) Readdir(count int) ([]os.FileInfo, error) {
f.n.mu.Lock()
defer f.n.mu.Unlock()
if !f.n.mode.IsDir() {
if !f.n.mode.IsDir() && !(f.n.mode&os.ModeSymlink > 0) {
return nil, os.ErrInvalid
}
old := f.pos
@ -564,7 +564,7 @@ func (f *memFile) Write(p []byte) (int, error) {
f.n.mu.Lock()
defer f.n.mu.Unlock()
if f.n.mode.IsDir() {
if f.n.mode.IsDir() || (f.n.mode&os.ModeSymlink > 0) {
return 0, os.ErrInvalid
}
if f.pos < len(f.n.data) {
@ -693,7 +693,7 @@ func copyFiles(ctx context.Context, fs FileSystem, src, dst string, overwrite bo
}
}
if srcStat.IsDir() {
if srcStat.IsDir() || (srcStat.Mode()&os.ModeSymlink > 0) {
if err := fs.Mkdir(ctx, dst, srcPerm); err != nil {
return http.StatusForbidden, err
}
@ -752,12 +752,12 @@ func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.
// This implementation is based on Walk's code in the standard path/filepath package.
err := walkFn(name, info, nil)
if err != nil {
if info.IsDir() && err == filepath.SkipDir {
if (info.IsDir() || (info.Mode()&os.ModeSymlink > 0)) && err == filepath.SkipDir {
return nil
}
return err
}
if !info.IsDir() || depth == 0 {
if (!info.IsDir() && !(info.Mode()&os.ModeSymlink > 0)) || depth == 0 {
return nil
}
if depth == 1 {
@ -785,7 +785,7 @@ func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.
} else {
err = walkFS(ctx, fs, depth, filename, fileInfo, walkFn)
if err != nil {
if !fileInfo.IsDir() || err != filepath.SkipDir {
if (!fileInfo.IsDir() && !(fileInfo.Mode()&os.ModeSymlink > 0)) || err != filepath.SkipDir {
return err
}
}