最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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)因文件過大而內(nèi)存暴漲的問題)

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

1 流式下載:io.Copy

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

通過io.Copy可以保證內(nèi)存占用一直處于一個比較穩(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)可中斷的流式下載的詳細內(nèi)容,更多關(guān)于golang實現(xiàn)流式下載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

青神县| 宜阳县| 平凉市| 绵阳市| 高密市| 阜南县| 河津市| 霍山县| 五常市| 北京市| 南澳县| 宜城市| 延寿县| 涿州市| 油尖旺区| 兴业县| 民乐县| 黄石市| 海伦市| 车致| 基隆市| 永川市| 岱山县| 札达县| 平利县| 唐河县| 丰镇市| 孟津县| 开远市| 麻城市| 永善县| 崇阳县| 波密县| 洛浦县| 泗洪县| 紫阳县| 鄂尔多斯市| 上饶县| 海原县| 体育| 桐柏县|