If I have some code, like the example below, that fetches an image from a link and then saves it to disk, what is the best way to pass around the image data?
I thought about using ioutil.ReadAll(res.Body)
to convert it to []byte
but passing that around seems expensive, although I can't tell from the documentation whether or not it returns a slice or an array. I also tried returning a pointer to res.Body
, a *io.ReadCloser
type, but I couldn't figure out how to properly call the .Close()
method on the pointed to interface.
I understand that moving the save code into the FetchImage
function would probably be the easiest way to solve this but I would like to have these pieces separate if possible.
type ImageData struct {
Data io.ReadCloser
Name string
}
func FetchImage(url string) (io.ReadCloser, error) {
res, err := http.Get(url)
if err != nil {
return nil, err
}
return res.Body, nil
}
func Save(data *ImageData) error {
defer data.Data.Close()
file, err := os.Create(data.Name)
defer file.Close()
if err != nil {
return err
}
_, err = io.Copy(file, data.Data)
if err != nil {
return err
}
return nil
}
func main() {
body, err := fetcher.FetchImage("https://imgur.com/asdf.jpg")
if err != nil {
panic(err)
}
imageData := ImageData{body, "asdf.jpg"}
saver := Saver{config.BaseDir, 1}
err = saver.Save(&imageData)
if err != nil {
panic(err)
}
}
Additionally, I am very new to Go so if there's anything in this code that looks bad please let me know.