golang实现断点续传

这里只展示了核心代码部分,使用了封装request和response的gin框架,若小伙伴没使用可用改成go自带的http。

func SendFile(r *gin.Context) {
	//断点续传标志
	var range_ext = r.GetHeader("Range")

	filePath := "." + r.Request.URL.Path

	if filePath == "./" {
		filePath = "./index.html"
	}

	parts := strings.Split(filePath, ".")

	print(parts[len(parts)-1] + "\n")
	print(filePath + "\n")

	file1, _ := os.Open(filePath)
	data, _ := ioutil.ReadAll(file1)

	//获取content type
	contentType := extensionToContentType[parts[len(parts)-1]]
	print(contentType + "\n")

	if file1 == nil {
		r.HTML(404, "404.html", gin.H{})
		return
	}

	var FileStreamSize int64 = r.Request.ContentLength

	if FileStreamSize == 0 {
		fi, _ := file1.Stat()
		FileStreamSize = fi.Size()
	}
	var FileStreamLen string = strconv.FormatInt(FileStreamSize, 10)

	//Range字段为空, 直接发送数据
	if range_ext == "" {
		r.Writer.Header().Set("Content-Type", contentType)
		r.Writer.Header().Set("Content-Length", FileStreamLen)
		r.Writer.WriteHeader(200)
		r.Writer.Write(data)
		return
	}

	//Range字段非空,断点续传模式
	fmt.Printf("part  download...\n")
	fmt.Printf("head range is:%s\n", range_ext)

	length := strings.Index(range_ext, "=")
	allRange := range_ext[length+1:]

	remove := strings.Index(allRange, "-")
	prelen := allRange[:remove]
	behind := allRange[remove+1:]
	var start int64
	var end int64

	if prelen == "" {
		behindint, _ := strconv.ParseInt(behind, 10, 64)
		start = FileStreamSize - behindint
		end = FileStreamSize
		FileStreamLen = behind
	}

	if behind == "" {
		prelenint, _ := strconv.ParseInt(prelen, 10, 64)
		start = prelenint
		end = FileStreamSize
		FileStreamLen = strconv.FormatInt(end-start, 10)
	}

	if prelen != "" && behind != "" {
		prelenint, _ := strconv.ParseInt(prelen, 10, 64)
		behindint, _ := strconv.ParseInt(behind, 10, 64)
		start = prelenint
		end = behindint
		FileStreamLen = strconv.FormatInt(end-start+1, 10)
	}

	allRange = allRange + strconv.FormatInt(FileStreamSize, 10)
	fmt.Printf("start:%v, end:%v, allRange:%v, FileSize:%v, FileLen:%v\n", start, end, allRange, FileStreamSize, FileStreamLen)

	r.Writer.Header().Set("Content-Type", contentType)
	r.Writer.Header().Set("Accept-Ranges", "bytes")
	r.Writer.Header().Set("Content-Length", FileStreamLen)
	r.Writer.Header().Set("Content-Range", "bytes "+allRange+"/"+strconv.FormatInt(FileStreamSize, 10))

	r.Writer.WriteHeader(206)

	r.Writer.Write(data[start:end])

	fmt.Println("file Wirte finished")
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(Golang)是一种开源的编程语言,它具有简洁、高效和并发性强的特点。在Go语言中,函数是一等公民,可以像其他类型的值一样进行传递和操作。 下面是介绍Golang实现函数的几个关键点: 1. 函数定义:使用关键字`func`来定义函数,语法如下: ``` func 函数名(参数列表) 返回值列表 { // 函数体 } ``` 例如,定义一个计算两个整数之和的函数: ``` func add(a, b int) int { return a + b } ``` 2. 函数参数:函数可以接受零个或多个参数,参数之间用逗号分隔。参数可以指定类型,例如`a, b int`表示两个整数类型的参数。如果多个参数的类型相同,可以只在最后一个参数后面指定类型。 例如,定义一个计算两个整数之差的函数: ``` func subtract(a, b int) int { return a - b } ``` 3. 函数返回值:函数可以返回一个或多个值。返回值列表放在函数名后面的括号中,并指定返回值的类型。如果函数没有返回值,可以省略返回值列表。 例如,定义一个计算两个整数之积和商的函数: ``` func multiplyAndDivide(a, b int) (int, float64) { return a * b, float64(a) / float64(b) } ``` 4. 匿名函数:在Go语言中,可以使用匿名函数,即没有函数名的函数。匿名函数可以直接赋值给变量,也可以作为参数传递给其他函数。 例如,定义一个匿名函数并将其赋值给变量: ``` add := func(a, b int) int { return a + b } ``` 5. 函数作为参数和返回值:在Go语言中,函数可以作为参数传递给其他函数,也可以作为函数的返回值。 例如,定义一个接受函数作为参数的函数: ``` func operate(a, b int, operation func(int, int) int) int { return operation(a, b) } ``` 以上是Golang实现函数的基本介绍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值