I am wanting to serve a .ZIP file that is created on the fly, without having to write it to disk (I/O will slow down performance) and serve it to the client over HTTP.
Here is how I first attempted this:
func ZipServe(W http.ResponseWriter, R *http.Request) {
buf := new(bytes.Buffer)
writer := zip.NewWriter(buf)
// for the sake of this demonstration, this is the data I will zip
data := ioutil.ReadFile("randomfile.jpg")
f, err := writer.Create("randomfile.jpg")
if err != nil {
fmt.Println(err)
}
_, err = f.Write(data)
if err != nil {
fmt.Println(err)
}
io.Copy(W, buf)
err := writer.Close()
if err != nil {
fmt.Println(err)
}
}
This is no good, as the .ZIP ends up being corrupt after downloading. I suppose the issue has to do with io.Copy; shall I be using a different method?
2) Check out the multifile document which includes the zipped file. 3) Select zip-file inside multifile document and select with right-click Windows commands -> 7-Zip -> Open archive. Zip packet content inside 7-zip window will open. 4) Open document editor (e.g. Word) with double-click and edit the document.
The first option is to select all of the desired files and add them to a new ZIP file. Organize the files on your desktop or within a folder. Select the files, then right-click to open the pull-down menu. Select your ZIP program, then click Add to ZIP File.
I found interesting this and just for testing came up with this:
http://play.golang.org/p/JKAde2jbR3
package main
import (
"archive/zip"
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func zipHandler(w http.ResponseWriter, r *http.Request) {
filename := "randomfile.jpg"
buf := new(bytes.Buffer)
writer := zip.NewWriter(buf)
data, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
f, err := writer.Create(filename)
if err != nil {
log.Fatal(err)
}
_, err = f.Write([]byte(data))
if err != nil {
log.Fatal(err)
}
err = writer.Close()
if err != nil {
log.Fatal(err)
}
w.Header().Set("Content-Type", "application/zip")
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.zip\"", filename))
//io.Copy(w, buf)
w.Write(buf.Bytes())
}
func main() {
http.HandleFunc("/zip", zipHandler)
http.ListenAndServe(":8080", nil)
}
I just add some headers like the Content-Type
and Content-Disposition
.
Also instead of using io.Copy(w, buf)
I am writing directly w.Write(buf.Bytes())
wondering if this is better? probably a more experienced user could clarify this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With