Can someone please explain "Readdir" and "Open" wrapper methods

huangapple go评论79阅读模式
英文:

Can someone please explain "Readdir" and "Open" wrapper methods

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我对Golang还不熟悉。有人可以解释一下,"Readdir"和"Open"包装方法是如何工作的吗?

这个例子来自Golang文档。
https://pkg.go.dev/net/http#example-FileServer-DotFileHiding

更具体地说,在"Readdir"方法中,语句files, err := f.File.Readdir(n)中有一个整数值n,但它是从哪里传递过来的,它是如何工作的。"Readdir"方法在程序中没有被调用。

类似地,在"Open"包装方法中,file, err := fsys.FileSystem.Open(name)

package main

import (
	"io/fs"
	"log"
	"net/http"
	"strings"
)

// containsDotFile报告name是否包含以句点开头的路径元素。
// 假定name由斜杠分隔,这是由http.FileSystem接口保证的。
func containsDotFile(name string) bool {
	parts := strings.Split(name, "/")
	for _, part := range parts {
		if strings.HasPrefix(part, ".") {
			return true
		}
	}
	return false
}

// dotFileHidingFile是dotFileHidingFileSystem中使用的http.File。
// 它用于包装http.File的Readdir方法,以便我们可以从输出中删除以句点开头的文件和目录。
type dotFileHidingFile struct {
	http.File
}

// Readdir是对嵌入的File的Readdir方法的包装,
// 它过滤掉所有以句点开头的文件。
func (f dotFileHidingFile) Readdir(n int) (fis []fs.FileInfo, err error) {
	files, err := f.File.Readdir(n)
	for _, file := range files { // 过滤掉句点文件
		if !strings.HasPrefix(file.Name(), ".") {
			fis = append(fis, file)
		}
	}
	return
}

// dotFileHidingFileSystem是一个隐藏"dot文件"不被提供的http.FileSystem。
type dotFileHidingFileSystem struct {
	http.FileSystem
}

// Open是对嵌入的FileSystem的Open方法的包装,
// 当name的路径中有以句点开头的文件或目录时,它会返回403权限错误。
func (fsys dotFileHidingFileSystem) Open(name string) (http.File, error) {
	if containsDotFile(name) { // 如果是句点文件,返回403响应
		return nil, fs.ErrPermission
	}

	file, err := fsys.FileSystem.Open(name)
	if err != nil {
		return nil, err
	}
	return dotFileHidingFile{file}, err
}

func main() {
	fsys := dotFileHidingFileSystem{http.Dir(".")}
	http.Handle("/", http.FileServer(fsys))
	log.Fatal(http.ListenAndServe(":8080", nil))
}
英文:

I'm new to Golang. Can someone please explain, how "Readdir" and "Open" wrapper methods are working?

This example is from Golang documentation.
https://pkg.go.dev/net/http#example-FileServer-DotFileHiding

More specifically, in the "Readdir" method, the statement files, err := f.File.Readdir(n) has n int value but from where it's passed and how it is working. "Readdir" method isn't called anywhere in the program.

Similarly in "Open" wrapper file, err := fsys.FileSystem.Open(name)

package main
import (
"io/fs"
"log"
"net/http"
"strings"
)
// containsDotFile reports whether name contains a path element starting with a period.
// The name is assumed to be a delimited by forward slashes, as guaranteed
// by the http.FileSystem interface.
func containsDotFile(name string) bool {
parts := strings.Split(name, "/")
for _, part := range parts {
if strings.HasPrefix(part, ".") {
return true
}
}
return false
}
// dotFileHidingFile is the http.File use in dotFileHidingFileSystem.
// It is used to wrap the Readdir method of http.File so that we can
// remove files and directories that start with a period from its output.
type dotFileHidingFile struct {
http.File
}
f
// Readdir is a wrapper around the Readdir method of the embedded File
// that filters out all files that start with a period in their name.
func (f dotFileHidingFile) Readdir(n int) (fis []fs.FileInfo, err error) {
files, err := f.File.Readdir(n)
for _, file := range files { // Filters out the dot files
if !strings.HasPrefix(file.Name(), ".") {
fis = append(fis, file)
}
}
return
}
// dotFileHidingFileSystem is an http.FileSystem that hides
// hidden "dot files" from being served.
type dotFileHidingFileSystem struct {
http.FileSystem
}
// Open is a wrapper around the Open method of the embedded FileSystem
// that serves a 403 permission error when name has a file or directory
// with whose name starts with a period in its path.
func (fsys dotFileHidingFileSystem) Open(name string) (http.File, error) {
if containsDotFile(name) { // If dot file, return 403 response
return nil, fs.ErrPermission
}
file, err := fsys.FileSystem.Open(name)
if err != nil {
return nil, err
}
return dotFileHidingFile{file}, err
}
func main() {
fsys := dotFileHidingFileSystem{http.Dir(".")}
http.Handle("/", http.FileServer(fsys))
log.Fatal(http.ListenAndServe(":8080", nil))
}

答案1

得分: 2

dotFileHidingFileSystem 类型包装了 http.FileSystem,本身也是一个 http.FileSystem。

dotFileHidingFile 类型包装了 http.File,本身也是一个 http.File。

由于这两个结构类型都 嵌入 了被包装的值,所以被包装的值上的所有方法都会被提升为包装类型上的方法,除非包装类型本身实现了该方法。如果你对嵌入的概念不熟悉,请阅读 Effective Go 中关于嵌入的部分

net/http 的 FileServer 调用了 http.FileSystem 和 http.File 接口上的方法。

file server 调用文件系统的 Open 方法来打开文件。dotFileHidingFileSystem 实现了该方法,它通过调用被包装的文件系统来打开文件,并返回一个包装了该文件的 dotFileHidingFile。

如果文件是一个目录,file server 调用文件的 Readdir 方法来获取目录中的文件列表。文件服务器指定了 n 的值。dotFileHidingFile 实现的 Readdir 方法通过调用被包装文件的 Readdir 方法,并过滤掉结果中的点文件。

有关 Readdir 的 n 参数的文档,请参阅 ReadDirFile 文档。

英文:

The dotFileHidingFileSystem type wraps an http.FileSystem and is itself an http.FileSystem.

The dotFileHidingFile type wraps an http.File and is itself an http.File.

Because these two struct types embed the wrapped value, all of the methods on the wrapped value are promoted to methods on the wrapper type unless the wrapper type itself implements the method. Read the Effective Go section on embedding if you are not familiar with the embedding concept.

The net/http FileServer calls the methods on the http.FileSystem and http.File interfaces.

The file server calls the file system Open method to open a file. The dotFileHidingFileSystem implementation of that method calls through to the wrapped file system to open the file and returns a dotFileHidingFile wrapper around that file.

If the file is a directory, the file server calls the file Readdir method to get a listing of the files in the directory. The file server specifies the value of n. The dotFileHidingFile implementation of the Readdir method calls through the the wrapped file Readdir method and filters dot files out of the result.

See the ReadDirFile documentation for documentation on the n argument to Readdir.

huangapple
  • 本文由 发表于 2022年6月4日 10:08:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/72496587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定