DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 963,274 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Dhanush Gopinath
Dhanush Gopinath

Posted on

Concurrent HTTP downloads usingΒ Go

Recently for an implementation of feature in Geektrust, we had to download multiple images from the internet and use it. This had to be an efficient implementation. This post is a brief explanation of the simple implementation done using goroutines and channels.

Image courtesyβ€Šβ€”β€Šhttps://hackernoon.com/why-we-love-concurrency-and-you-should-too-c64c2d08a059

Go has an http package which has simple APIs to do HTTP operations. For e.g. if you want to download a page all you need to do is this.

resp, err := http.Get("http://example.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
Enter fullscreen mode Exit fullscreen mode

Given below is the implementation of downloading a file from a public URL and using it as bytes.

For downloading multiple files concurrently you can use the help of goroutines and channels.

In the above code snippet, we initialise two channels, one for sending the file downloaded as []byte type and another for sending any errors that happened while downloading.

We then loop though all the urls and call the downloadFile method for each of them in a goroutine. These goroutines are executed concurrently and so the for loop is finished processing in no time. Inside the goroutine each file is downloaded and we get back bytes and error.

If there is an error in the download, then the error is pushed to the error channel and nil value is pushed to the done channel. If there is no error then the bytes are pushed to the done channel and a nil entry is pushed to the error channel.

An array of byte arrays is declared to collect the downloaded files back. We again loop through as many times as there are URLs to collect the byte array back from the done channel.

bytesArray = append(bytesArray, <-done)  
if err := <-errch; err != nil {   
   errStr = errStr + " " + err.Error()  
}
Enter fullscreen mode Exit fullscreen mode

These two lines inside the for loop wait for the done and the error channel to receive data. Once the data has arrived, it increments the loop count. Bytes are appended to the array of bytes while error string is appended, if there are any errors.

You have now downloaded the files concurrently and they are available as an array of bytes. All just using simple Go code.

This article was first published on my personal tech blog.

Top comments (2)

Collapse
 
rhymes profile image
rhymes

Hi Dhanush, just fyi: I think you forgot to copy the code of the "download_mutliple_files.go" code I see on your medium blog.

Thanks for the article, very interesting!

Collapse
 
dhanushgopinath profile image
Dhanush Gopinath Author

Thanks. I have fixed it. :)

Take a look at this:

Settings

Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. πŸ›