123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package main
- import (
- "bytes"
- "fmt"
- "io"
- "mime/multipart"
- "net/http"
- "os"
- )
- func main() {
- filePath := "C:\\Users\\lx\\Downloads\\ubuntu-22.04.4-live-server-amd64.iso"
- chunkSize := int64(1024 * 1024 * 100) // 100MB 分块大小
- fileID := "unique-file-id" // 文件唯一标识符
- // 打开文件
- file, err := os.Open(filePath)
- if err != nil {
- panic(err)
- }
- defer file.Close()
- // 获取文件信息
- fileInfo, err := file.Stat()
- if err != nil {
- panic(err)
- }
- fileSize := fileInfo.Size()
- // 计算总块数
- totalChunks := (fileSize + chunkSize - 1) / chunkSize
- // 记录已上传的块(可以保存在文件或数据库中)
- uploadedChunks := make(map[int64]bool)
- // 遍历每个块并上传
- for chunkIndex := int64(0); chunkIndex < totalChunks; chunkIndex++ {
- if uploadedChunks[chunkIndex] {
- // 如果该块已经上传,则跳过
- continue
- }
- // 创建块的缓冲区
- buffer := make([]byte, chunkSize)
- readBytes, err := file.Read(buffer)
- if err != nil && err != io.EOF {
- panic(err)
- }
- if readBytes == 0 {
- break
- }
- // 上传块
- err = uploadChunk(buffer[:readBytes], chunkIndex, totalChunks, fileID, fileInfo.Name())
- if err != nil {
- fmt.Printf("Failed to upload chunk %d: %v\n", chunkIndex, err)
- continue
- }
- // 记录已上传块
- uploadedChunks[chunkIndex] = true
- }
- }
- func uploadChunk(chunkData []byte, chunkIndex, totalChunks int64, fileID, filename string) error {
- // 创建 multipart 请求体
- body := new(bytes.Buffer)
- writer := multipart.NewWriter(body)
- // 添加文件块
- part, err := writer.CreateFormFile("file", filename)
- if err != nil {
- return err
- }
- part.Write(chunkData)
- // 添加其他字段
- writer.WriteField("chunkIndex", fmt.Sprintf("%d", chunkIndex))
- writer.WriteField("totalChunks", fmt.Sprintf("%d", totalChunks))
- writer.WriteField("fileID", fileID)
- // 关闭 multipart 编写器
- err = writer.Close()
- if err != nil {
- return err
- }
- // 发送请求
- req, err := http.NewRequest("POST", "http://localhost:8080/upload", body)
- if err != nil {
- return err
- }
- req.Header.Set("Content-Type", writer.FormDataContentType())
- client := &http.Client{}
- resp, err := client.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
- // 读取响应
- respBody, err := io.ReadAll(resp.Body)
- if err != nil {
- return err
- }
- fmt.Printf("Response: %s\n", string(respBody))
- return nil
- }
|