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ù)制