I have a handler function which looks like below:
func DownloadFileHandler(w http.ResponseWriter, r *http.Request) {
SetResponseHeaders(w, r)
if r.Method == "OPTIONS" {
return
}
var err error
var responseCode int = http.StatusBadRequest
vars := mux.Vars(r)
file := vars["file"]
var n int64 = 0
var reader io.Reader
Filename := "images/" + file
f, err := os.Open(Filename)
if err != nil {
err = errors.New("File not found")
goto Error
}
reader = bufio.NewReader(f)
settings.WriteDebugLog(time.Now())
n, err = io.Copy(w, reader) // this takes a long time if the file is large
settings.WriteDebugLog(time.Now())
settings.WriteDebugLog(n / 1024 / 1024)
responseCode = http.StatusOK
settings.WriteLog(r, responseCode, nil, GetCurrentFuncName())
return
Error:
WriteErrorResponse(w, responseCode, err)
settings.WriteLog(r, responseCode, err, GetCurrentFuncName())
}
But if it is a large file (more than 1GB), the io.Copy takes quite a long time (best case: 1G 13 seconds shown below) and the download process in browser doesn't show up until the process of io.Copy completes. Is there a way to achieve my goal more efficiently? I want the download process to show up in my browser right after I send the download request.
2017/05/16 22:32:29 Debug: 2017-05-16 22:32:29.967499719 +0900 JST
2017/05/16 22:32:36 Debug: 2017-05-16 22:32:36.980914163 +0900 JST
2017/05/16 22:32:36 Debug: 1097
I tried calling io.Copy with "go io.Copy" then the download process shows up soon but the file size is 0.
You can do by directing the download to the file server
Please note, that the filename or path you use is relative to your current working directory.