`

Golang: 利用 channel (管道) 技术多线程下载图片

 
阅读更多

利用 channel (管道) 技术多线程下载图片.

 

package main

import (
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
	//"strconv"
	"strings"
	"sync"
)

var urlist = [...]string{"http://stock.591hx.com/article/2014-12-03/0000850005s.shtml"}
var album chan string
var w sync.WaitGroup
var dir string

func main() {
	dir = "tmp_chenjo/"
	err := os.Mkdir(dir, 0777)
	if err != nil {
		isexist := os.IsExist(err)
		log.Println(isexist)
	}
	album = make(chan string, 200)

	for _, v := range urlist {
		w.Add(1)
		go GetAlbum(v)
		w.Wait()
	}
}

func GetAlbum(url string) {
	data := GetUrl(url)
	body := string(data)
	//<img src="http://stock.591hx.com/images/hnimg/201412/03/64/13418266510200941552.jpg" alt="" /></p>
	part := regexp.MustCompile(`<img src="(.*)" alt="" />`)
	match := part.FindAllStringSubmatch(body, -1)
	for _, v := range match {

		if m, _ := regexp.MatchString(`.*/hnimg/201412/03/.*\.jpg`, v[1]); !m {
			continue
		}
		//println(v[1])
		album <- v[1]
		w.Add(1)
		go GetItem()
	}
	w.Done()

}

func GetItem() {
	url := <-album
	println(url)
	defer func() {
		ret := recover()
		if ret != nil {
			log.Println(ret)
			w.Done()
		} else {
			w.Done()
		}
	}()

	//data := GetUrl(url)
	//if len(data) > 10 {
	//body := string(data)
	//part := regexp.MustCompile(`bigimgsrc="(.*)"`)
	//match := part.FindAllStringSubmatch(body, -1)
	//for _, v := range match {
	str := strings.Split(url, "/")
	length := len(str)
	source := GetUrl(url)
	name := str[length-1]
	file, err := os.Create(dir + name)
	if err != nil {
		panic(err)
	}
	size, err := file.Write(source)
	defer file.Close()
	if err != nil {
		panic(err)
	}
	log.Println(size)
	//}
	//}
}

func GetUrl(url string) []byte {
	ret, err := http.Get(url)
	if err != nil {
		log.Println(url)
		status := map[string]string{}
		status["status"] = "400"
		status["url"] = url
		panic(status)
	}
	body := ret.Body
	data, _ := ioutil.ReadAll(body)
	return data
}

 

 console output:

G:/share/Golang/Golang.exe [G:/share/Golang]

2015/01/18 21:54:29 true

http://stock.591hx.com/images/hnimg/201412/03/64/13418266510200941552.jpg

http://stock.591hx.com/images/hnimg/201412/03/7/10886141709285175583.jpg

http://stock.591hx.com/images/hnimg/201412/03/0/5391574706574741364.jpg

http://stock.591hx.com/images/hnimg/201412/03/1/5405780767459854941.jpg

http://stock.591hx.com/images/hnimg/201412/03/16/13722698761317688276.jpg

http://stock.591hx.com/images/hnimg/201412/03/7/16853951343108680551.jpg

http://stock.591hx.com/images/hnimg/201412/03/50/17680852843413447062.jpg

http://stock.591hx.com/images/hnimg/201412/03/34/14366548421421579970.jpg

http://stock.591hx.com/images/hnimg/201412/03/4/17141924098089490820.jpg

2015/01/18 21:54:30 29968

2015/01/18 21:54:30 28697

2015/01/18 21:54:30 51586

2015/01/18 21:54:30 53031

2015/01/18 21:54:30 31234

2015/01/18 21:54:31 47618

2015/01/18 21:54:31 54649

2015/01/18 21:54:31 40422

2015/01/18 21:54:31 155527

成功: 进程退出代码 0.

 

 

分享到:
评论

相关推荐

    golang开发中channel使用

    Channel类似于管道,允许数据在并发组件之间流动,确保数据在正确的时间传递到正确的协程,同时避免了数据竞争和其他并发问题。 ### Channel的概念与语法 1. **概念**:Channel是一个先进先出(FIFO)的数据结构,...

    golang实现多用户通信系统

    总结来说,这个基于Golang的多用户通信系统利用了Golang的TCP套接字编程能力,通过Redis实现了高效的数据存储和检索,借助协程和管道实现了并发处理,从而能同时服务于多个用户。这样的设计保证了系统的高并发性和低...

    golang并发编程实战

    1. **多线程下载文件**:通过创建多个goroutine并行下载大文件的不同部分,然后通过channel汇总结果,最终合成完整的文件。 2. **并发爬虫**:利用goroutine和channel构建高效的网络爬虫,实现网页的快速抓取和解析...

    godl:使用Golang构建同步下载器

    同步下载器与我们常见的多线程下载工具类似,它允许多个文件部分同时下载,以提高下载速度。godl就是这样一个工具,它利用Go语言的goroutine和channel特性,实现了高效的文件下载功能。 1. **Go语言基础** Go语言...

    golang基础入门

    Channel则用于在goroutine之间安全地传递数据,它是类型化的管道,可以用来连接并发的函数。 Go语言的基础入门还包括了json数据的处理。Go语言的标准库中的encoding/json包,提供了对JSON数据的编码和解码功能。这...

    参考资料-管道基础.zip

    例如,在Golang中,goroutines通过通道(Channel)实现数据的同步和传递,这种机制类似于管道。 4. **软件开发工具**:许多开发工具也利用管道原理,如Git的rebasing或merging流程,将多个提交顺序地应用到分支上。...

    GoLang-concurrency:GoLang的并发练习

    并发在Go中是一个核心特性,通过 goroutines 和 channels 实现,这使得编写能够充分利用多核处理器的高效程序变得相对简单。让我们深入探讨Go语言的并发特性。 **一、goroutines** goroutine 是Go语言中的轻量级...

    Go语言协程goroutine和管道channel教程.PDF

    ### Go语言协程goroutine与管道channel教程 #### 一、引言 Go语言作为一种现代编程语言,以其简洁高效的语法和强大的并发模型受到广大开发者的喜爱。其中,协程(goroutine)和管道(channel)是Go语言实现高效并发...

    开源项目-golang-go.zip

    - 并发支持:Go语言内置goroutine和channel,提供轻量级线程和通信机制,使得并发编程变得简单高效。 - 垃圾回收:自动内存管理,减轻程序员负担,提高程序安全性。 - 静态链接:默认情况下,Go程序会静态链接...

    golang基础之Gocurrency并发

    在Golang编程语言中,Gocurrency并发是其核心特性之一,它使得程序员能够编写高效、可扩展的多任务程序。Golang的并发模型基于CSP(Communicating Sequential Processes)理论,强调通过通信来共享内存,而不是通过...

    Go-ChanBroker一个goroutine的Broker类似于kafka

    在Go语言中,goroutine是一种轻量级线程,由语言本身支持,可以并发运行,而channel则是goroutine之间通信的桥梁,允许数据在不同的goroutine之间安全地传递。Go-ChanBroker利用这两个特性构建了一个类似Kafka的消息...

    sslot:golang中插槽的服务器端

    Goroutine是轻量级线程,而channel则可以被看作是goroutine之间的通信管道。在服务器端编程中,我们可能会创建多个goroutine来处理不同的任务或连接,而插槽可能是指分配给这些goroutine的特定工作区域或通信接口。 ...

    go语言练手小项目,聊天室,高并发特性(goroutine+管道)

    在本项目中,我们将探讨如何利用Go语言构建一个聊天室,特别是其内置的高并发特性——goroutine和管道(channel)。 Goroutine是Go语言中的轻量级线程,它们比操作系统线程更轻便、更高效,因为它们由Go运行时管理...

    ringbuf:Go 的线程安全环形缓冲区实现

    这个库提供了一个简单的无锁实现,意味着它不依赖于Go的互斥锁(mutex)来保证数据的一致性,而是利用原子操作来确保在多线程环境下的安全性。无锁实现通常比使用锁的实现具有更低的延迟和更高的吞吐量,这对于高...

    concurrency-in-go:并发教程-Golang

    在Golang中,并发是其独特特性之一,它利用了Go协程(Goroutines)和通道(Channels)来实现高效的并行执行。本教程将深入探讨Go语言中的并发编程,帮助你理解如何利用这些工具来提升程序性能。 1. **Go协程...

    Go语言的管道Channel用法实例

    这个例子展示了如何利用channel在并发执行的多个函数之间进行结果的汇总,体现了Go语言在并发编程方面的便利性。在实际的软件开发中,channel的使用场景非常广泛,比如在分布式系统中,可以用来实现服务之间的通信,...

    go语言channel实现多核并行化运行的方法

    在Go语言中,`channel`是并发编程的核心组成部分,它提供了一种安全地在多个goroutine(轻量级线程)之间传递数据的方式,从而实现了多核并行化运行。 在Go语言中,通过`channel`实现多核并行化运行的方法主要基于...

    《学习Go语言》中文版(201200730) PDF 高清

    - **高效**:Go语言内置了并发支持,通过goroutine和channel机制简化了多线程编程的复杂度。 - **跨平台**:Go语言可以轻松地编译为不同操作系统(如Linux、Windows等)下的二进制文件,实现跨平台部署。 - **...

    golang并发编程的实现

    Channel是Go中用于goroutine间通信的管道,它具有以下特点: 1. 支持发送和接收数据。 2. 保证操作的同步性,发送和接收操作会阻塞goroutine,直到另一方准备好进行操作。 3. 可以是无缓冲的,也可以是有缓冲的。 ...

Global site tag (gtag.js) - Google Analytics