英文:
Two folders in the file system as one virtual folder in the path of the site address (web server in Go)
问题
我在文件系统中有两个文件夹,分别是"files1"和"files2"。
我可以将文件系统中的一个文件夹作为站点地址路径下的一个虚拟文件夹进行托管,代码如下:
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./files1"))))
如何将"files1"和"files2"文件夹的内容都托管到站点地址路径"/public/"下呢?
英文:
I have two folders in the file system "files1" and "files2".
I can host one folder in the file system as one virtual folder in the path of the site address like this:
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./files1"))))
How can I host the contents of the "files1" and "files2" folders on the same path of the site address "/public/" ?
答案1
得分: 4
一个简单的解决方案是实现http.FileSystem接口。
以下是示例代码:
package main
import (
"errors"
"io/fs"
"net/http"
)
func main() {
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(mergedDir{
Dir1: http.Dir("./files1"),
Dir2: http.Dir("./files2"),
})))
http.ListenAndServe(":8080", nil)
}
type mergedDir struct {
Dir1 http.Dir // 首先尝试访问Dir1,因此它具有更高的优先级。
Dir2 http.Dir
}
func (d mergedDir) Open(name string) (http.File, error) {
f, err := d.Dir1.Open(name)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return d.Dir2.Open(name)
}
}
return f, err
}
我已经使用以下目录结构进行了测试:
├── files1
│ ├── f1-1.txt
│ └── f1-sub
│ └── f1-s.txt
└── files2
├── f1-1.txt
├── f2-1.txt
└── f2-sub
└── f2-s.txt
有两个f1-1.txt
,因为首先尝试访问files1
,所以会提供files1
中的版本。
更新:
根据作者的要求,这是支持多个目录的mergedDir
的另一个版本:
type mergedDir struct {
Dirs []http.Dir
}
func (d mergedDir) Open(name string) (http.File, error) {
for _, dir := range d.Dirs {
f, err := dir.Open(name)
if err == nil {
return f, nil
}
if !errors.Is(err, fs.ErrNotExist) {
return f, err
}
}
return nil, fs.ErrNotExist
}
英文:
A simple solution is to implement the http.FileSystem interface.
Here is the demo:
package main
import (
"errors"
"io/fs"
"net/http"
)
func main() {
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(mergedDir{
Dir1: "./files1",
Dir2: "./files2",
})))
http.ListenAndServe(":8080", nil)
}
type mergedDir struct {
Dir1 http.Dir // Dir1 will be tried first so it has higher priority.
Dir2 http.Dir
}
func (d mergedDir) Open(name string) (http.File, error) {
f, err := d.Dir1.Open(name)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return d.Dir2.Open(name)
}
}
return f, err
}
I have tested with this directory structure:
├── files1
│   ├── f1-1.txt
│   └── f1-sub
│   └── f1-s.txt
└── files2
├── f1-1.txt
├── f2-1.txt
└── f2-sub
└── f2-s.txt
There are two f1-1.txt
, the one in files1
is served because files1
is tried first.
Update:
Another version of mergedDir
to support multiple directories as requested by the author:
type mergedDir struct {
Dirs []http.Dir
}
func (d mergedDir) Open(name string) (http.File, error) {
for _, dir := range d.Dirs {
f, err := dir.Open(name)
if err == nil {
return f, nil
}
if !errors.Is(err, fs.ErrNotExist) {
return f, err
}
}
return nil, fs.ErrNotExist
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论