使用Golang提供PDF文件服务

huangapple go评论86阅读模式
英文:

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)
    }
}

使用Golang提供PDF文件服务

英文:

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)
    }
}

使用Golang提供PDF文件服务

答案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.

huangapple
  • 本文由 发表于 2017年7月25日 19:35:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/45302083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定