亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

golang并發(fā)下載多個(gè)文件的方法

 更新時(shí)間:2019年07月11日 09:15:30   作者:moxiaomomo  
今天小編就為大家分享一篇golang并發(fā)下載多個(gè)文件的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

背景說明

假設(shè)有一個(gè)分布式文件系統(tǒng),現(xiàn)需要從該系統(tǒng)中并發(fā)下載一部分文件到本地機(jī)器。

已知該文件系統(tǒng)的部分節(jié)點(diǎn)ip, 以及需要下載的文件fileID列表,并能通過這些信息來拼接下載地址。

其中節(jié)點(diǎn)ip列表保存在xx_node.txt, 要下載的fileID保存在xx_fileID.txt中。

代碼示例

package main

import (
  "bufio"
  "flag"
  "fmt"
  "io"
  "math/rand"
  "net/http"
  "os"
  "time"
)

var (
  clustername = flag.String("clustername", "c1", "download clustername")
)

// 逐行讀取文件內(nèi)容
func ReadLines(fpath string) []string {
  fd, err := os.Open(fpath)
  if err != nil {
    panic(err)
  }
  defer fd.Close()

  var lines []string
  scanner := bufio.NewScanner(fd)
  for scanner.Scan() {
    lines = append(lines, scanner.Text())
  }
  if err := scanner.Err(); err != nil {
    fmt.Fprintln(os.Stderr, err)
  }

  return lines
}

// 實(shí)現(xiàn)單個(gè)文件的下載
func Download(clustername string, node string, fileID string) string {
  nt := time.Now().Format("2006-01-02 15:04:05")
  fmt.Printf("[%s]To download %s\n", nt, fileID)

  url := fmt.Sprintf("http://%s/file/%s", node, fileID)
  fpath := fmt.Sprintf("/yourpath/download/%s_%s", clustername, fileID)
  newFile, err := os.Create(fpath)
  if err != nil {
    fmt.Println(err.Error())
    return "process failed for " + fileID
  }
  defer newFile.Close()

  client := http.Client{Timeout: 900 * time.Second}
  resp, err := client.Get(url)
  defer resp.Body.Close()

  _, err = io.Copy(newFile, resp.Body)
  if err != nil {
    fmt.Println(err.Error())
  }
  return fileID
}

func main() {
  flag.Parse()

  // 從文件中讀取節(jié)點(diǎn)ip列表
  nodelist := ReadLines(fmt.Sprintf("%s_node.txt", *clustername))
  if len(nodelist) == 0 {
    return
  }

  // 從文件中讀取待下載的文件ID列表
  fileIDlist := ReadLines(fmt.Sprintf("%s_fileID.txt", *clustername))
  if len(fileIDlist) == 0 {
    return
  }

  ch := make(chan string)

  // 每個(gè)goroutine處理一個(gè)文件的下載
  r := rand.New(rand.NewSource(time.Now().UnixNano()))
  for _, fileID := range fileIDlist {
    node := nodelist[r.Intn(len(nodelist))]
    go func(node, fileID string) {
      ch <- Download(*clustername, node, fileID)
    }(node, fileID)
  }

  // 等待每個(gè)文件下載的完成,并檢查超時(shí)
  timeout := time.After(900 * time.Second)
  for idx := 0; idx < len(fileIDlist); idx++ {
    select {
    case res := <-ch:
      nt := time.Now().Format("2006-01-02 15:04:05")
      fmt.Printf("[%s]Finish download %s\n", nt, res)
    case <-timeout:
      fmt.Println("Timeout...")
      break
    }
  }
}

小結(jié)

下載時(shí)沒有用到默認(rèn)的http Client, 并指定了超時(shí)時(shí)間;

下載文件時(shí)調(diào)用了系統(tǒng)調(diào)用, goroutine會(huì)被掛起;

下載文件完成后會(huì)喚醒被掛起的goroutine, 該goroutine執(zhí)行完后面的代碼后便退出;

全局超時(shí)控制,超時(shí)后主線程退出。

以上這篇golang并發(fā)下載多個(gè)文件的方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • go項(xiàng)目實(shí)現(xiàn)mysql接入及web?api的操作方法

    go項(xiàng)目實(shí)現(xiàn)mysql接入及web?api的操作方法

    這篇文章主要介紹了go項(xiàng)目實(shí)現(xiàn)mysql接入以及web api,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Go通過goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程

    Go通過goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程

    多協(xié)程文件上傳是指利用多線程或多協(xié)程技術(shù),同時(shí)上傳一個(gè)或多個(gè)文件,以提高上傳效率和速度,本文給大家介紹了Go通過goroutine實(shí)現(xiàn)多協(xié)程文件上傳的基本流程,需要的朋友可以參考下
    2024-05-05
  • Go?基本數(shù)據(jù)類型與字符串相互轉(zhuǎn)換方法小結(jié)

    Go?基本數(shù)據(jù)類型與字符串相互轉(zhuǎn)換方法小結(jié)

    這篇文章主要介紹了Go基本數(shù)據(jù)類型與字符串相互轉(zhuǎn)換,將string類型轉(zhuǎn)換成基本類型時(shí),必須確保string類型是有效的,文中補(bǔ)充介紹了Go基本數(shù)據(jù)類型和其字符串表示之間轉(zhuǎn)換,結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Go json反序列化“null“的問題解決

    Go json反序列化“null“的問題解決

    本文主要介紹了Go json反序列化“null“的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Go語言LeetCode題解961在長度2N的數(shù)組中找出重復(fù)N次元素

    Go語言LeetCode題解961在長度2N的數(shù)組中找出重復(fù)N次元素

    這篇文章主要為大家介紹了Go語言LeetCode題解961在長度2N的數(shù)組中找出重復(fù)N次元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • golang快速實(shí)現(xiàn)網(wǎng)頁截圖的方法

    golang快速實(shí)現(xiàn)網(wǎng)頁截圖的方法

    這篇文章主要介紹了golang快速實(shí)現(xiàn)網(wǎng)頁截圖的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 手把手帶你走進(jìn)Go語言之條件表達(dá)式

    手把手帶你走進(jìn)Go語言之條件表達(dá)式

    條件表達(dá)式由條件運(yùn)算符構(gòu)成,并常用條件表達(dá)式構(gòu)成一個(gè)賦值語句,本文給大家介紹了在Go語言中條件表達(dá)式的具體用法,講述的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值
    2021-09-09
  • Go連接并操作SQLite數(shù)據(jù)庫基本步驟

    Go連接并操作SQLite數(shù)據(jù)庫基本步驟

    在這篇文章中,我們將詳細(xì)描述如何在?Go?語言中使用?SQLite?數(shù)據(jù)庫,我們將會(huì)從如何在?Go?中安裝和使用?SQLite?驅(qū)動(dòng)包開始講起,然后逐步介紹如何創(chuàng)建數(shù)據(jù)庫連接,執(zhí)行?SQL?查詢,處理返回的數(shù)據(jù)以及關(guān)閉數(shù)據(jù)庫連接
    2024-01-01
  • Go中strings的常用方法詳解

    Go中strings的常用方法詳解

    這篇文章主要介紹了Go中strings的常用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 深入string理解Golang是怎樣實(shí)現(xiàn)的

    深入string理解Golang是怎樣實(shí)現(xiàn)的

    這篇文章主要為大家介紹了深入string理解Golang是怎樣實(shí)現(xiàn)的原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04

最新評論