尝试在Go语言中使用通道,但数据未正确发送/接收到通道中。

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

Trying to use channels in go but data is not properly sent/received into the channel

问题

希望能够快速解析非常多相似的URL(只有一个'id'元素在每个URL中不同),并将响应体转储到一个通道中,稍后主函数将查询该通道并用于构建文本文件。

getpageCanal()函数内部,响应体似乎没问题,但之后,我不明白为什么通道没有正确加载响应体字符串。

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	initial := "https://www1.medion.de/downloads/index.pl?op=detail&id="
	ending := "&type=treiber&lang=uk"

	links := []string{}
	os.Remove("dump.txt")
	dumpFile, _ := os.Create("dump.txt")
	c := make(chan string)
	for i := 16000; i < 16004; i++ {
		links = append(links, initial+fmt.Sprint(i)+ending)
	}
	fmt.Println(links[0])
	for _, link := range links {
        //希望将此处变为goroutine,但首先我需要让它正常工作
		getpageCanal(c, link)
	}

	for el := range c {
		fmt.Println(el)
		n, err := dumpFile.WriteString(el)
		if err != nil {
			fmt.Println(err)
		}
		if n == 0 {
			fmt.Println("主函数中没有写入任何内容")
		}
	}
}

func getpageCanal(canal chan string, url string) {
	defer close(canal)
	page, err := http.Get(url)
	if err != nil {
		fmt.Println("你搞砸了,小伙子")
	}
	content, er2 := ioutil.ReadAll(page.Body)
	//fmt.Println(content)
	if er2 != nil {
		fmt.Println(er2)
	}
	canal <- string(content)
}

<details>
<summary>英文:</summary>

The hope is to quickly parse a very large number of similar URLs (only one &#39;id&#39; element differs from one to the next) and dump the response body into a channel that will later be queried by the main function and used to build a text file.

Inside the `getpageCanal()` function, the body seems to be ok, but after that, I don&#39;t understand why the channel doesn&#39;t properly load the body string.

```golang
package main

import (
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;net/http&quot;
	&quot;os&quot;
)

func main() {
	initial := &quot;https://www1.medion.de/downloads/index.pl?op=detail&amp;id=&quot;
	ending := &quot;&amp;type=treiber&amp;lang=uk&quot;

	links := []string{}
	os.Remove(&quot;dump.txt&quot;)
	dumpFile, _ := os.Create(&quot;dump.txt&quot;)
	c := make(chan string)
	for i := 16000; i &lt; 16004; i++ {
		links = append(links, initial+fmt.Sprint(i)+ending)
	}
	fmt.Println(links[0])
	for _, link := range links {
        //the hope is to make this a go routine, but first I need to just make it work
		getpageCanal(c, link)
	}

	for el := range c {
		fmt.Println(el)
		n, err := dumpFile.WriteString(el)
		if err != nil {
			fmt.Println(err)
		}
		if n == 0 {
			fmt.Println(&quot; nothing written in main&quot;)
		}
	}
}

func getpageCanal(canal chan string, url string) {
	defer close(canal)
	page, err := http.Get(url)
	if err != nil {
		fmt.Println(&quot;you done fucked up, boy&quot;)
	}
	content, er2 := ioutil.ReadAll(page.Body)
	//fmt.Println(content)
	if er2 != nil {
		fmt.Println(er2)
	}
	canal &lt;- string(content)
}


</details>


# 答案1
**得分**: 1

根据第一个评论的指示(在每次调用后不关闭通道,并将对工作函数的调用设置为goroutine),我现在将为您提供一个可工作的版本:

```go
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	initial := "https://www1.medion.de/downloads/index.pl?op=detail&id="
	ending := "&type=treiber&lang=uk"

	links := []string{}
	os.Remove("dump.txt")
	dumpFile, _ := os.Create("dump.txt")
	c := make(chan string)
	for i := 16000; i < 16004; i++ {
		links = append(links, initial+fmt.Sprint(i)+ending)
	}
	fmt.Println(links[0])
	for _, link := range links {
		go getpageCanal(c, link)
	}

	for el := range c {
		fmt.Println(el)
		n, err := dumpFile.WriteString(el)
		if err != nil {
			fmt.Println(err)
		}
		if n == 0 {
			fmt.Println(" nothing written in main")
		}
	}
}

func getpageCanal(canal chan string, url string) {
	//defer close(canal)
	page, err := http.Get(url)
	if err != nil {
		fmt.Println("you done fucked up, boy")
	}
	content, er2 := ioutil.ReadAll(page.Body)
	//fmt.Println(content)
	if er2 != nil {
		fmt.Println(er2)
	}
	canal <- string(content)
}

希望对您有所帮助!

英文:

After modifying the code as instructed by the first comments (not closing the channel after each call and making the call to the worker function a go routine) I will now provide you with a working version:

package main
import (
&quot;fmt&quot;
&quot;io/ioutil&quot;
&quot;net/http&quot;
&quot;os&quot;
)
func main() {
initial := &quot;https://www1.medion.de/downloads/index.pl?op=detail&amp;id=&quot;
ending := &quot;&amp;type=treiber&amp;lang=uk&quot;
links := []string{}
os.Remove(&quot;dump.txt&quot;)
dumpFile, _ := os.Create(&quot;dump.txt&quot;)
c := make(chan string)
for i := 16000; i &lt; 16004; i++ {
links = append(links, initial+fmt.Sprint(i)+ending)
}
fmt.Println(links[0])
for _, link := range links {
go getpageCanal(c, link)
}
for el := range c {
fmt.Println(el)
n, err := dumpFile.WriteString(el)
if err != nil {
fmt.Println(err)
}
if n == 0 {
fmt.Println(&quot; nothing written in main&quot;)
}
}
}
func getpageCanal(canal chan string, url string) {
//defer close(canal)
page, err := http.Get(url)
if err != nil {
fmt.Println(&quot;you done fucked up, boy&quot;)
}
content, er2 := ioutil.ReadAll(page.Body)
//fmt.Println(content)
if er2 != nil {
fmt.Println(er2)
}
canal &lt;- string(content)
}

huangapple
  • 本文由 发表于 2021年10月31日 01:22:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/69780498.html
匿名

发表评论

匿名网友

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

确定