欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang實現(xiàn)可中斷的流式下載功能

 更新時間:2024年01月02日 09:12:45   作者:NPE~  
這篇文章主要給大家介紹了golang實現(xiàn)可中斷的流式下載,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下

golang實現(xiàn)可中斷的流式下載

最近有一個需要實現(xiàn)下載功能:

從服務器上讀取文件,返回一個ReadCloser

在用戶磁盤上創(chuàng)建文件,通過io.Copy實現(xiàn)文件下載(io.Copy是流式的操作,不會出現(xiàn)因文件過大而內存暴漲的問題)

通過context實現(xiàn)暫停

1 流式下載:io.Copy

這里拷貝文件我們選擇的是io.Copy而非是通過ioutil.ReadAll()將body中返回的數(shù)據(jù)一次性讀取到內存

通過io.Copy可以保證內存占用一直處于一個比較穩(wěn)定的水平

2 可中斷:context

通過封裝io.Copy實現(xiàn)

  • 將io.Copy封裝為一個方法,方法里傳入context,外部通過context.WithCancel()控制流式拷貝的暫停

3 全部代碼

這里演示我通過讀取S3的一個對象下載到本地

/*
	通過io.Copy實現(xiàn)可中斷的流復制
*/
var (
	ak       = "99999999999999999999"
	sk       = "9999999999999999999999999999999999999999"
	endpoint = "http://xx.xx.xx.xx:8060"
	bucket   = "test-bucket"
	key      = "d_xp/2G/2G.txt"
)

func main() {
	s3Client := osg.Client.GetS3Client(ak, sk, endpoint)
	ctx, cancelFunc := context.WithCancel(context.Background())
	object, err := s3Client.GetObject(ctx, &s3.GetObjectInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(key),
	})
	go func() {
		time.Sleep(time.Second * 10)
		cancelFunc()
		log.Infof("canceled...")
	}()
	if err != nil {
		log.Errorf("%v", err)
		return
	}
	body := object.Body
	defer body.Close()
	file, err := os.Create("/Users/ziyi/GolandProjects/MyTest/demo_home/io_demo/target.txt")
	if err != nil {
		log.Errorf("%v", err)
		return
	}
	defer file.Close()
	_, err = FileService.Copy(ctx, file, body)
	if err != nil {
		log.Errorf("%v", err)
		return
	}

}

type fileService struct {
	sem *semaphore.Weighted
}

var FileService = &fileService{
	sem: semaphore.NewWeighted(1),
}

type IoCopyCancelledErr struct {
	errMsg string
}

func (e *IoCopyCancelledErr) Error() string {
	return fmt.Sprintf("io copy error, %s", e.errMsg)
}

func NewIoCopyCancelledErr(msg string) *IoCopyCancelledErr {
	return &IoCopyCancelledErr{
		errMsg: msg,
	}
}

type readerFunc func(p []byte) (n int, err error)

func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) }

//通過ctx實現(xiàn)可中斷的流拷貝
// Copy closable copy
func (s *fileService) Copy(ctx context.Context, dst io.Writer, src io.Reader) (int64, error) {
	// Copy will call the Reader and Writer interface multiple time, in order
	// to copy by chunk (avoiding loading the whole file in memory).
	// I insert the ability to cancel before read time as it is the earliest
	// possible in the call process.
	size, err := io.Copy(dst, readerFunc(func(p []byte) (int, error) {
		select {
		// if context has been canceled
		case <-ctx.Done():
			// stop process and propagate "context canceled" error
			return 0, NewIoCopyCancelledErr(ctx.Err().Error())
		default:
			// otherwise just run default io.Reader implementation
			return src.Read(p)
		}
	}))
	return size, err
}

以上就是golang實現(xiàn)可中斷的流式下載的詳細內容,更多關于golang實現(xiàn)流式下載的資料請關注腳本之家其它相關文章!

相關文章

  • golang進行xml文件解析的操作方法

    golang進行xml文件解析的操作方法

    本文介紹了Go語言中解析XML文件的幾種方法:小文件解析、大文件流式解析和復雜結構解析,對于小文件,使用標準庫中的encoding/xml包;對于大文件,采用流式解析以避免內存溢出,對于復雜結構的XML文件,推薦使用第三方庫github.com/beevik/etree
    2024-11-11
  • 創(chuàng)建Go工程化項目布局詳解

    創(chuàng)建Go工程化項目布局詳解

    這篇文章主要介紹了創(chuàng)建Go工程化項目布局詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • golang數(shù)組和切片作為參數(shù)和返回值的實現(xiàn)

    golang數(shù)組和切片作為參數(shù)和返回值的實現(xiàn)

    本文主要介紹了golang數(shù)組和切片作為參數(shù)和返回值的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 詳解go-zero是如何做路由管理的

    詳解go-zero是如何做路由管理的

    go-zero 是一個微服務框架,包含了 web 和 rpc 兩大部分,而對于 web 框架來說,路由管理是必不可少的一部分,那么本文就來探討一下 go-zero 的路由管理是怎么做的吧
    2023-08-08
  • Golang的循環(huán)語句和循環(huán)控制語句詳解

    Golang的循環(huán)語句和循環(huán)控制語句詳解

    循環(huán)語句為了簡化程序中有規(guī)律的重復性操作,需要用到循環(huán)語句,和其他大多數(shù)編程語言一樣,GO的循環(huán)語句有for循環(huán),不同的是沒有while循環(huán),而循環(huán)控制語句可以改變循環(huán)語句的執(zhí)行過程,下面給大家介紹下go循環(huán)語句和循環(huán)控制語句的相關知識,一起看看吧
    2021-11-11
  • 線上問題排查之golang使用json進行對象copy

    線上問題排查之golang使用json進行對象copy

    這篇文章主要介紹了線上問題排查之golang使用json進行對象copy,文章圍繞golang使用json進行對象copy的內存溢出問題排查展開詳細內容需要的小伙伴可以參考一下
    2022-06-06
  • Go使用Gin+mysql實現(xiàn)增刪改查的詳細實例

    Go使用Gin+mysql實現(xiàn)增刪改查的詳細實例

    golang本身沒有提供連接mysql的驅動,但是定義了標準接口供第三方開發(fā)驅動,下面這篇文章主要給大家介紹了關于Go使用Gin+mysql實現(xiàn)增刪改查的相關資料,需要的朋友可以參考下
    2022-12-12
  • 一鍵定位Golang線上服務內存泄露的秘籍

    一鍵定位Golang線上服務內存泄露的秘籍

    內存泄露?別讓它拖垮你的Golang線上服務!快速掌握Go語言服務內存泄漏排查秘籍,從此問題無處遁形,一文讀懂如何精準定位與有效解決Golang應用中的內存問題,立即閱讀,讓性能飛升!
    2024-01-01
  • goland中npm無法使用的問題及解決

    goland中npm無法使用的問題及解決

    這篇文章主要介紹了goland中npm無法使用的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Golang變量直接初始化的方法詳解

    Golang變量直接初始化的方法詳解

    在 Go 語言中,我們常用的數(shù)據(jù)結構有在Go語言中,你可以初始化不同的數(shù)據(jù)結構,例如數(shù)組、切片、結構體、指針、map等,本文將給大家介紹一下Golang變量直接初始化的方法,需要的朋友可以參考下
    2023-08-08

最新評論