限速下载

php版本:

<?php 
// 将发送到客户端的本地文件 
$local_file='abc.zip'; 
// 文件名 
$download_file='your-download-name.zip'; 
// 设置下载速率(=> 31.2 kb/s) 
$download_rate=31.2; 
if(file_exists($local_file)&&is_file($local_file)){ 
 header('Cache-control: private');// 发送 headers 
 header('Content-Type: application/octet-stream'); 
 header('Content-Length: '.filesize($local_file)); 
 header('Content-Disposition: filename='.$download_file); 
 flush();// 刷新内容 
 $file=fopen($local_file,"r"); 
 while (!feof($file)){ 
  print fread($file,round($download_rate*1024));// 发送当前部分文件给浏览者 
  flush();// flush 内容输出到浏览器端 
  sleep(1);// 终端1秒后继续 
 } 
 fclose($file);// 关闭文件流 
}else{ 
 die('Error: 文件 '.$local_file.' 不存在!'); 
} 

go版本:

package main

import (
    "bufio"
    //"bufio"
    //"bytes"
    "context"
    "errors"
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/juju/ratelimit"
    "io"

    //"io"
    "log"
    "net/http"
    "syscall"
    "time"

    "os/signal"

    //"github.com/juju/ratelimit"

    "os"
    "path/filepath"
)


type Web struct {
    cache_path string
}

func (w *Web) create_cache()  {
    w.cache_path = filepath.Join("./", "file_server_cache")

    if _, err := os.Stat(w.cache_path); err != nil {
        // not exists
        if err := os.MkdirAll(w.cache_path, os.ModePerm); err != nil {
            log.Fatal(err)
        }
    }
}
func (w *Web) index(c *gin.Context)  {
    //all_file, _ := get_all_file(w.cache_path)
    //fmt.Println(all_file)
    //c.JSON(200, gin.H{
    //    "message": "pong",
    //})

}
func (w *Web) download_handler(c *gin.Context)  {
    download_file := c.Query("file_name")
    file_path := "./file_server_cache/" + download_file
    if _, err := os.Stat(file_path); err != nil {
        c.JSON(200, gin.H{
            "code": "1",
            "msg":"error, download_file not exists",
        })
        return
    }

    c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", download_file))
    c.Writer.Header().Add("Content-Type", "application/octet-stream")
    //c.File("./file_server_cache/"+download_file)

    file, _ := os.Open(file_path)
    // new 一个速度限制器,每秒传输 100 Kb(第一个值 是下载速度,第二个是会影响下载速度,建议两个一样)
    bucket := ratelimit.NewBucketWithRate(100 * 1024,100 * 1024)
    reader:= bufio.NewReader(file)
    io.Copy(c.Writer,ratelimit.Reader(reader,bucket))

}
func get_all_file(dir string) ([][]string, error) {
    dirs, err := os.ReadDir(dir)
    if err != nil {
        return nil, err
    }

    var all_file [][]string
    for _, v := range dirs {
        if !v.IsDir() {
            single_file := []string{v.Name(), filepath.Join(dir, v.Name())}
            all_file = append(all_file, single_file)
        }
    }
    return all_file, nil
}

//参考地址:https://www.cnblogs.com/gopher-zero/p/14754526.html
func main() {
    w := Web{}
    w.create_cache()

    router := gin.Default()
    router.GET("/", w.index)
    router.GET("/download", w.download_handler)

    srv := &http.Server{
        Addr:    ":8080",
        Handler: router,
    }

    go func() {
        err := srv.ListenAndServe()
        if err!=nil&&errors.Is(err,http.ErrServerClosed){
            log.Printf("listen:%s\n",err)
        }
    }()

    quit := make(chan os.Signal)

    signal.Notify(quit,syscall.SIGINT,syscall.SIGTERM)
    <-quit
    log.Println("Shutting down server..")

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    err := srv.Shutdown(ctx)
    if err!=nil{
        log.Fatal("Server forced to shutdown:", err)
    }
    log.Println("Server exiting")
}

 

posted @ 2022-11-04 13:46  菜的掉渣  阅读(81)  评论(0编辑  收藏  举报