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