使用Go并發下載圖片資源

jopen 10年前發布 | 13K 次閱讀 Go語言 Google Go/Golang開發

對爬蟲已爬到的數據進行下載,響應時間與請求量成正比。

package img

import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "io" "net/http" "os" "runtime" "strconv" "sync" "time" )

const ( DataRoot = "./tmp/" // 存放封面圖的根目錄 TimeoutLimit = 10 // 設置超時時間 )

// 表示章節ID和封面URL的對應關系 type VolumeCover struct { VolumeID int Url string Lock sync.Mutex Msg chan string Flag bool    "timeout_flag" }

// 將圖片下載并保存到本地 func SaveImage(vc *VolumeCover) { res, err := http.Get(vc.Url) defer res.Body.Close() if err != nil { vc.Msg <- (strconv.Itoa(vc.VolumeID) + " HTTP_ERROR") } // 創建文件 dst, err := os.Create(DataRoot + strconv.Itoa(vc.VolumeID) + ".jpg") if err != nil { vc.Msg <- (strconv.Itoa(vc.VolumeID) + " OS_ERROR") } // 生成文件 io.Copy(dst, res.Body) // goroutine通信 vc.Lock.Lock() vc.Msg <- "in" vc.Flag = true vc.Lock.Unlock() }

func Start(name string, password string, limit int) error { runtime.GOMAXPROCS(4) sl, err := sql.Open("mysql", name+":"+password+"@/slnovel?charset=utf8") defer sl.Close() if err != nil { return err } // 構造SELECT語句并檢索 queryStr := "SELECT VolumeID, ImageUrl FROM volume " if limit > 0 { queryStr += "limit " + strconv.Itoa(limit) } rows, err := sl.Query(queryStr) defer rows.Close() if err != nil { return err }

// 構建列表
i := 0
vclist := make([]*VolumeCover, limit)
for rows.Next() {
    vc := &VolumeCover{}
    if err := rows.Scan(&vc.VolumeID, &vc.Url); err != nil {
        return err
    }
    vc.Msg = make(chan string, 1)
    //vc.To = make(chan bool, 1)
    vc.Lock = *new(sync.Mutex)
    vclist[i] = vc
    i++
}

// start goroutines
for i := 0; i < len(vclist); i++ {
    go SaveImage(vclist[i])
    go func(i int) {
        time.Sleep(TimeoutLimit * time.Second)
        if vclist[i].Flag == false {
            vclist[i].Msg <- "out"
        }
    }(i)
}

// 阻塞地獲取結果
for i := 0; i < len(vclist); i++ {
    func(c *VolumeCover) {
        select {
        case m := <-c.Msg:
            fmt.Println(m)
        }

    }(vclist[i])
}
return nil

}</pre></span>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!