英文:
serving up pdfs using golang
问题
只是想知道你们是否可以帮助解决一些代码问题。
它可以用来提供图片,但不能提供 PDF 宣传册。
提前感谢。
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
filename := "/var/www/filedipenser/brochure.pdf"
streamPDFbytes, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
b := bytes.NewBuffer(streamPDFbytes)
w.Header().Set("Content-type", "application/pdf")
if _, err := b.WriteTo(w); err != nil {
fmt.Fprintf(w, "%s", err)
}
w.Write([]byte("PDF Generated"))
})
err := http.ListenAndServe(":4111", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
fmt.Println(err)
}
}
英文:
just wondering if you guys can help with some code.
It works serving up images but not a pdf brochure.
Thanks in advance
func main(){
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
filename := "/var/www/filedipenser/brochure.pdf"
streamPDFbytes, err := ioutil.ReadFile( filename )
if err != nil {
fmt.Println(err)
os.Exit(1)
}
b := bytes.NewBuffer(streamPDFbytes)
w.Header().Set("Content-type", "application/pdf")
if _, err := b.WriteTo(w); err != nil {
fmt.Fprintf(w, "%s", err)
}
w.Write([]byte("PDF Generated"))
})
err := http.ListenAndServe(":4111", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
fmt.Println(err)
}
}
答案1
得分: 10
代码有点低效,但似乎是可以工作的。然而,一些PDF查看器可能对你在HTTP响应流的末尾添加的多余输出比较敏感。删除w.Write([]byte("PDF Generated"))
,因为这会破坏输出。如果你想进行调试,可以将其更改为fmt.Println
。
低效性是因为你将整个PDF文件加载到内存中,然后发送给客户端。对于大文件来说,这会浪费内存。你最好是直接从文件中打开并通过io.Copy将其流式传输到响应(一个io.Writer)中。类似这样:
// 打开文件
f, err := os.Open(filename)
if err != nil {
fmt.Println(err)
w.WriteHeader(500)
return
}
defer f.Close()
// 设置头部
w.Header().Set("Content-type", "application/pdf")
// 流式传输到响应
if _, err := io.Copy(w, f); err != nil {
fmt.Println(err)
w.WriteHeader(500)
}
你显然希望更好地处理错误,这只是一个示例。然而,当遇到错误时,重要的是向客户端提供HTTP错误响应,以便它知道请求失败了。
英文:
The code is a bit inefficient but it appears to be working. However, some PDF viewers might be sensitive to the extraneous output you are adding to the end of the HTTP response stream. Remove w.Write([]byte("PDF Generated"))
as this will be corrupting the output. You could change this to a fmt.Println
if you wanted for debugging purposes.
The inefficiency is because you are loading the entire PDF file into memory to then send to the client. For large files this will waste memory. You would be better to open the file and stream directly from the file (an io.Reader) to the response (an io.Writer) using io.Copy. Something like:
// Open file
f, err := os.Open(filename)
if err != nil {
fmt.Println(err)
w.WriteHeader(500)
return
}
defer f.Close()
//Set header
w.Header().Set("Content-type", "application/pdf")
//Stream to response
if _, err := io.Copy(w, f); err != nil {
fmt.Println(err)
w.WriteHeader(500)
}
You would obviously want to handle errors better, this is just an example. However, it is important the client is provided an HTTP error response when you encounter an error so it is aware that the request failed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论