当使用http.Get()时出现无效的内存地址或空指针解引用。

huangapple go评论93阅读模式
英文:

invalid memory address or nil pointer dereference when use http.Get()

问题

我刚开始学习Go语言,我写了一个小示例,从txt文件中读取图片URL,将URL放入一个数组中,然后将响应保存到文件中。

以下是我的代码:

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("文件加载:%s \n", line)
			picUrl = append(picUrl, string(line))
		} else {
			file.Close()
			break
		}
	}
	fmt.Printf("文件加载完成,准备下载 \n")
	fetchPic(picUrl)

}

func fetchPic(picUrl []string) {

	var file string
	for key, value := range picUrl {

		fmt.Printf("键:%d,行:%s \n\n", key, value)
		httpRequest, err := http.Get(string(value))
		fmt.Print("加载完成 \n")

		httpRequest.Body.Close()
		result, readErr := ioutil.ReadAll(httpRequest.Body)
		if readErr == nil {
			file = "pics/" + string(key) + ".jpg"
			ioutil.WriteFile(file, result, 0777)
			fmt.Print("写入完成 \n")
		}
		length := len(string(result))
		fmt.Printf("长度:%d", length)
		if err == nil {
			httpRequest = nil
		} else {
			fmt.Print("加载失败!!!!!! \n")
		}
		defer httpRequest.Body.Close()
	}

}

运行代码后,我得到了以下错误:

键:0,行:
加载完成 
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中,每行一个URL。有人可以帮忙吗?谢谢。

英文:

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 \n", line)
picUrl = append(picUrl, string(line))
} else {
file.Close()
break
}
}
fmt.Printf("file loaded,read to download \n")
fetchPic(picUrl)
}
func fetchPic(picUrl []string) {
var file string
for key, value := range picUrl {
fmt.Printf("key is : %d,this line is %s \n\n", key, value)
httpRequest, err := http.Get(string(value))
fmt.Print("load ok \n")
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 \n")
}
len := len(string(result))
fmt.Printf("length is %d", len)
if err == nil {
httpRequest = nil
//result = nil
} else {
fmt.Print("load falt!!!!!!!!! \n")
}
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

答案1

得分: 6

在执行httpRequest, err := http.Get(string(value))之后,你正在从httpRequest.Body中无条件地读取,而没有检查err:如果http.Get失败,你将无法从httpRequest.Body中读取有效数据。

经验法则:立即检查每一个错误。

英文:

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.

答案2

得分: 2

这对我来说似乎工作得很好

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 \n\n", key, value)
httpRequest, err := http.Get(string(value))
fmt.Print("load ok \n")
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 \n")
}
len := len(string(result))
fmt.Printf("length is %d", len)
if err == nil {
httpRequest = nil
//result = nil
} else {
fmt.Print("load falt!!!!!!!!! \n")
}
}
}

上述代码输出以下结果:

正在运行...
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
成功:进程以代码 0 退出。
英文:

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 \n\n", key, value)
httpRequest, err := http.Get(string(value))
fmt.Print("load ok \n")
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 \n")
}
len := len(string(result))
fmt.Printf("length is %d", len)
if err == nil {
httpRequest = nil
//result = nil
} else {
fmt.Print("load falt!!!!!!!!! \n")
}
}
}

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.

答案3

得分: 0

我输入了这段代码并进行了测试,没有遇到任何问题。

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 \n\n", 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)
  }

}

答案

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
英文:

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 \n\n", 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

huangapple
  • 本文由 发表于 2014年1月10日 20:11:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/21044079.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定