Go的新手(我正在做的第一个简单项目)。
问题:如何从URL获取图像然后将其保存到我的计算机中?
这是我到目前为止所拥有的:
package main
import (
"fmt"
"net/http"
"image"
"io/ioutil"
)
func main() {
url := "http://i.imgur.com/m1UIjW1.jpg"
// don't worry about errors
response, _ := http.Get(url);
defer response.Body.Close()
m, _, err := image.Decode(response.Body)
error := ioutil.WriteFile("/images/asdf.jpg", m, 0644)
}
但是,当我运行此代码时,我得到cannot use m (type image.Image) as type []byte in function argument
我假设我必须将image.Image(变量m
)转换为未定义的字节数量?这是正确的方法吗?
答案 0 :(得分:32)
无需解码文件。只需将响应正文复制到您打开的文件即可。以下是修改示例中的交易:
response.Body
是一个数据流,实现了Reader
接口 - 这意味着您可以在其上顺序调用Read
,就像它是一个打开的文件一样。 Writer
接口。这是相反的 - 它是您可以调用Write
的流。io.Copy
“补丁”读者和作者,使用读者流并将其内容写入Writer。 这是我最喜欢的关于go - 隐式接口的事情之一。您不必声明您正在实现接口,您只需实现它以在某些上下文中使用。这允许混合和匹配不需要知道与其交互的其他代码的代码。
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
)
func main() {
url := "http://i.imgur.com/m1UIjW1.jpg"
// don't worry about errors
response, e := http.Get(url)
if e != nil {
log.Fatal(e)
}
defer response.Body.Close()
//open a file for writing
file, err := os.Create("/tmp/asdf.jpg")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// Use io.Copy to just dump the response body to the file. This supports huge files
_, err = io.Copy(file, response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println("Success!")
}
答案 1 :(得分:2)
package main
import (
"io"
"net/http"
"os"
"fmt"
)
func main() {
img, _ := os.Create("image.jpg")
defer img.Close()
resp, _ := http.Get("http://i.imgur.com/Dz2r9lk.jpg")
defer resp.Body.Close()
b, _ := io.Copy(img, resp.Body)
fmt.Println("File size: ", b)
}
答案 2 :(得分:0)
response.Body
的类型是什么?您应该将其转换为[]byte
(如果不是)并将其写入磁盘。除非您有理由将数据视为图像,否则没有理由使用image
类。只需将数据视为一系列字节并将其写入磁盘即可。
答案 3 :(得分:0)
您也可以使用 ReadFrom
方法:
package main
import (
"net/http"
"os"
)
func main() {
r, e := http.Get("https://i.imgur.com/m1UIjW1.jpg")
if e != nil {
panic(e)
}
defer r.Body.Close()
f, e := os.Create("m1UIjW1.jpg")
if e != nil {
panic(e)
}
defer f.Close()
f.ReadFrom(r.Body)
}