php小編柚子在介紹Web服務(wù)器路徑中的虛擬文件夾時(shí)提到了文件系統(tǒng)中的兩個(gè)文件夾作為站點(diǎn)地址的一部分。在Go語言中,這種虛擬文件夾的概念被廣泛應(yīng)用于Web服務(wù)器的路徑設(shè)置中。通過將這兩個(gè)文件夾作為站點(diǎn)地址的一部分,可以實(shí)現(xiàn)更靈活的文件路徑管理和訪問控制。這種設(shè)計(jì)模式不僅簡(jiǎn)化了站點(diǎn)文件的組織,還提供了更好的安全性和可維護(hù)性。通過虛擬文件夾的概念,開發(fā)人員可以更加方便地對(duì)站點(diǎn)資源進(jìn)行管理和控制。
問題內(nèi)容
我的文件系統(tǒng)中有兩個(gè)文件夾“files1”和“files2”。
我可以將文件系統(tǒng)中的一個(gè)文件夾作為站點(diǎn)地址路徑中的一個(gè)虛擬文件夾托管,如下所示:
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("./files1"))))
登錄后復(fù)制
如何將“files1”和“files2”文件夾的內(nèi)容托管在站點(diǎn)地址“/public/”的同一路徑上?
解決方法
一個(gè)簡(jiǎn)單的解決方案是實(shí)現(xiàn) http.filesystem 接口。
這是演示:
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
}
登錄后復(fù)制
我已經(jīng)用這個(gè)目錄結(jié)構(gòu)進(jìn)行了測(cè)試:
├── files1
│?? ├── f1-1.txt
│?? └── f1-sub
│?? └── f1-s.txt
└── files2
├── f1-1.txt
├── f2-1.txt
└── f2-sub
└── f2-s.txt
登錄后復(fù)制
有兩個(gè)f1-1.txt,由于先嘗試files1,所以服務(wù)的是files1中的。
更新:
按照作者的要求,mergeddir的另一個(gè)版本支持多個(gè)目錄:
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
}
登錄后復(fù)制






