I just start to learn Go lang,I wrote a small demo,read picture urls from txt,put urls in an array,then Save the Response into a file.
Here is my code
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
)
func main() {
fileName := "meinv.txt"
file, _ := os.Open(fileName)
picUrl := make([]string, 2000)
reader := bufio.NewReader(file)
for {
line, _, err := reader.ReadLine()
if err != io.EOF {
fmt.Printf("file load %s
", line)
picUrl = append(picUrl, string(line))
} else {
file.Close()
break
}
}
fmt.Printf("file loaded,read to download
")
fetchPic(picUrl)
}
func fetchPic(picUrl []string) {
var file string
for key, value := range picUrl {
fmt.Printf("key is : %d,this line is %s
", key, value)
httpRequest, err := http.Get(string(value))
fmt.Print("load ok
")
httpRequest.Body.Close()
result, readErr := ioutil.ReadAll(httpRequest.Body)
if readErr == nil {
file = "pics/" + string(key) + ".jpg"
ioutil.WriteFile(file, result, 0777)
fmt.Print("Write ok
")
}
len := len(string(result))
fmt.Printf("length is %d", len)
if err == nil {
httpRequest = nil
//result = nil
} else {
fmt.Print("load falt!!!!!!!!!
")
}
defer httpRequest.Body.Close()
}
}
run it ,and I got
key is : 0,this line is
load ok
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x40 pc=0x40123f]
goroutine 1 [running]:
runtime.panic(0x5f8300, 0x877688)
/usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
main.fetchPic(0xc21239d000, 0x38be7, 0x4223c)
/home/lyn/www/goOnDev/fetch.go:40 +0x24f
main.main()
/home/lyn/www/goOnDev/fetch.go:28 +0x1b8
exit status 2
meinv.txt ,one line per url Anyone help?THKS
You are reading unconditional from httpRequest.Body after doing httpRequest, err := http.Get(string(value))
without checking err: If http.Get
fails you won't have a valid httpRequest.Body
to read from.
Rule of thumb: Check each and every error immediately.
This seems to be working fine for me
func main() {
randomURLs := []string{"http://i.imgur.com/I7Rak2y.jpg", "http://i.imgur.com/XuM8GCN.jpg"}
fetchPic(randomURLs)
}
func fetchPic(picUrl []string) {
var file string
for key, value := range picUrl {
fmt.Printf("key is : %d,this line is %s
", key, value)
httpRequest, err := http.Get(string(value))
fmt.Print("load ok
")
defer httpRequest.Body.Close()
result, readErr := ioutil.ReadAll(httpRequest.Body)
if readErr == nil {
file = "pics/" + string(key) + ".jpg"
ioutil.WriteFile(file, result, 0777)
fmt.Print("Write ok
")
}
len := len(string(result))
fmt.Printf("length is %d", len)
if err == nil {
httpRequest = nil
//result = nil
} else {
fmt.Print("load falt!!!!!!!!!
")
}
}
}
The previous code output the following result:
Running...
key is : 0,this line is http://i.imgur.com/I7Rak2y.jpg
load ok
Write ok
length is 445661key is : 1,this line is http://i.imgur.com/XuM8GCN.jpg
load ok
Write ok
length is 746031
Success: process exited with code 0.
I type this code and test, I do not get any problem.
package main
import (
"os"
"fmt"
"bufio"
"net/http"
"io/ioutil"
)
func read_file(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
reader := bufio.NewScanner(file)
for reader.Scan() {
lines = append(lines, reader.Text())
}
return lines, reader.Err()
}
func main(){
lines, err := read_file("./file.txt")
if err != nil {
fmt.Println(err)
return
}
for key, value := range lines {
fmt.Printf("key is : %d,this line is %s
", key, value)
httpRequest, err := http.Get(value)
if err != nil {
fmt.Println(err)
return
}
defer httpRequest.Body.Close()
result, readErr := ioutil.ReadAll(httpRequest.Body)
if readErr != nil {
fmt.Println(err)
return
}
ioutil.WriteFile("./" + fmt.Sprintf("%d", key) + ".jpg", result, 0777)
}
}
Answer
key is : 0,this line is http://samsam.iteye.com/images/login_icon.png
key is : 1,this line is http://www.iteye.com/images/logo-small.gif
Shell
>>ls
0.jpg 1.jpg file.txt test.go