我們有一個程序,人們可以在他們的機器上編譯。它有一個HTTP接口,但也可以通過命令行調用。加載需要的文件,相對於絕對路徑
爲了給HTTP客戶端提供漂亮的錯誤頁面,我們希望提供錯誤頁面。我們使用go html/template
軟件包,使用了非常簡單的解決方案。
因此,爲了使程序找到模板,我們目前正在做的事:
func init() {
prefStr := "path/to/http/tmpl"
pathPrefix,err := filepath.Abs(prefStr)
if err != nil {
log.Warn("Template path %s is not available!", prefStr)
}
pathPrefix + "/err.html"
}
現在調試應用程序時,這通常效果很好 - 我們是在包的根目錄下,這樣filepath.Abs()
正確解析,像這樣: $GOPATH/github.com/user/repo/path/to/http/tmpl
(正確擴展$GOPATH
)
但是,當我們通過命令行通過可執行文件調用應用程序時,這是行不通的。命令行當然可以從文件系統的任何地方調用,以方便例如提供當前目錄中的文件作爲參數。
簡而言之,運行/some/other/path/on/fs/our-executable filename.txt
導致上述init()
函數因目錄錯誤拼接而中斷:它需要/some/other/path/on/fs/
來創建絕對路徑,這是錯誤的。因此,它與 panic: open /some/other/path/on/fs/path/to/http/tmpl/err.html: no such file or directory
我已經搜查,到目前爲止,只發現這個崩潰: How can I open files using relative paths in Go?
但這正是並不適用於我們。 另一種解決方案提出捆綁編譯的go資源,但這看起來很奇怪,因爲錯誤頁面是html文本。
我們也試過 https://stackoverflow.com/a/31464648/169252
,但它具有相同的效果。
我們如何確保路徑始終正確解析?這似乎是一件不應該太難完成的事情,但我們目前還沒有成功。
編輯:這不是問題How can I open files using relative paths in Go?的確切副本。正如我在問題文本中已經提到的那樣,我已經自己查閱了它。它建議使用filepath.Abs()
。但正如我的問題所闡明的那樣,對我們來說這不起作用,就像我們的可執行文件被從不同的地方調用一樣,filepath.Abs()
不會返回相同的值,因此對我們不起作用。
'path/to/http/tmpl'是絕對路徑嗎?這意味着它從文件系統的根目錄開始。例子'/ home/faboolous/abc/defg/tmpl' –
@ SamuelToh不,它不是絕對路徑,否則它不能移植。這是從回購的根源的相對路徑。 – faboolous
使用[go-bindata](https://github.com/jteeuwen/go-bindata)將模板編譯爲go二進制文件 – Mark