中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

golang怎么實現大文件傳輸和斷點續傳

小億
229
2024-02-28 14:39:31
欄目: 編程語言

在Golang中,可以使用HTTP協議來實現大文件傳輸和斷點續傳。下面是一個簡單的示例代碼:

package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
)

func handler(w http.ResponseWriter, r *http.Request) {
	file, err := os.Open("large_file.txt")
	if err != nil {
		fmt.Println("Error opening file: ", err)
		return
	}
	defer file.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println("Error getting file info: ", err)
		return
	}

	w.Header().Set("Content-Disposition", "attachment; filename=large_file.txt")
	w.Header().Set("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Length", strconv.FormatInt(fileInfo.Size(), 10))

	http.ServeContent(w, r, "large_file.txt", fileInfo.ModTime(), file)
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

在上面的示例中,我們首先打開了一個名為large_file.txt的大文件,并設置了HTTP響應頭,然后使用http.ServeContent函數將文件內容發送給客戶端。客戶端可以通過訪問http://localhost:8080來下載這個大文件。

如果要實現斷點續傳功能,可以通過檢查HTTP請求的Range頭來決定從文件的哪個位置開始傳輸。以下是一個修改后的示例代碼:

func handler(w http.ResponseWriter, r *http.Request) {
	file, err := os.Open("large_file.txt")
	if err != nil {
		fmt.Println("Error opening file: ", err)
		return
	}
	defer file.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println("Error getting file info: ", err)
		return
	}

	w.Header().Set("Content-Disposition", "attachment; filename=large_file.txt")
	w.Header().Set("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Length", strconv.FormatInt(fileInfo.Size(), 10))

	rangeHeader := r.Header.Get("Range")
	if rangeHeader != "" {
		startRange, endRange, err := parseRangeHeader(rangeHeader, fileInfo.Size())
		if err != nil {
			fmt.Println("Error parsing range header: ", err)
			return
		}
		w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", startRange, endRange, fileInfo.Size()))
		http.ServeContent(w, r, "large_file.txt", fileInfo.ModTime(), io.NewSectionReader(file, startRange, endRange-startRange+1))
	} else {
		http.ServeContent(w, r, "large_file.txt", fileInfo.ModTime(), file)
	}
}

func parseRangeHeader(rangeHeader string, fileSize int64) (int64, int64, error) {
	prefix := "bytes="
	if len(rangeHeader) < len(prefix) || rangeHeader[:len(prefix)] != prefix {
		return 0, 0, fmt.Errorf("Invalid range header format")
	}
	rangeStr := rangeHeader[len(prefix):]

	dashIndex := strings.IndexByte(rangeStr, '-')
	if dashIndex == -1 {
		return 0, 0, fmt.Errorf("Invalid range header format")
	}

	startRange, err := strconv.ParseInt(rangeStr[:dashIndex], 10, 64)
	if err != nil {
		return 0, 0, err
	}

	endRangeStr := rangeStr[dashIndex+1:]
	var endRange int64
	if endRangeStr == "" {
		endRange = fileSize - 1
	} else {
		endRange, err = strconv.ParseInt(endRangeStr, 10, 64)
		if err != nil {
			return 0, 0, err
		}
	}

	return startRange, endRange, nil
}

在上面的修改后的示例代碼中,我們首先解析了HTTP請求的Range頭,然后根據請求的范圍讀取文件內容,并設置Content-Range頭告知客戶端傳輸的內容范圍。

通過這種方式,我們可以實現大文件傳輸和斷點續傳的功能。在實際應用中,可以根據需要對代碼進行進一步的優化和擴展。

0
宣汉县| 马边| 巴林右旗| 秦皇岛市| 西昌市| 渝北区| 蒲江县| 闻喜县| 社会| 宁安市| 长顺县| 武邑县| 临颍县| 松桃| 教育| 柏乡县| 阿鲁科尔沁旗| 若尔盖县| 边坝县| 沙雅县| 嘉义市| 准格尔旗| 岳普湖县| 遵化市| 镇沅| 西充县| 德昌县| 溆浦县| 扎鲁特旗| 加查县| 武义县| 昌平区| 万盛区| 勃利县| 楚雄市| 宜黄县| 乌鲁木齐县| 贵州省| 汽车| 高邑县| 虎林市|