2015-01-09 5 views

risposta

2

C'è una versione aggiornata del the package on github

Si usa avvolgendo un io.Reader

Ecco un esempio completo che mostrerà la home page di Google veeeery sloooowly.

Questo involucro un'interfaccia per creare nuove funzionalità è molto buono. Vai allo stile e ne vedrai molte durante il tuo viaggio in Go.

package main 

import (
    "io" 
    "log" 
    "net/http" 
    "os" 

    "github.com/mxk/go-flowrate/flowrate" 
) 

func main() { 
    resp, err := http.Get("http://google.com") 
    if err != nil { 
     log.Fatalf("Get failed: %v", err) 
    } 
    defer resp.Body.Close() 

    // Limit to 10 bytes per second 
    wrappedIn := flowrate.NewReader(resp.Body, 10) 

    // Copy to stdout 
    _, err = io.Copy(os.Stdout, wrappedIn) 
    if err != nil { 
     log.Fatalf("Copy failed: %v", err) 
    } 
} 
+0

Sembra fantastico. Che dire del check-in se è stato raggiunto un limite come 5 MB? Dovrei semplicemente usare b: = make ([] byte, 5000000); wrappedIn.Read (b) ;? – John

+1

No, avvolgere 'io.Reader' in un [io.LimitedReader] (http://golang.org/pkg/io/#LimitedReader). –

+0

Ciò limita la velocità con cui si legge dal buffer TCP del kernel, non direttamente la velocità con cui si legge da remoto. Il buffer TCP locale si riempirà, la rete sarà inattiva mentre si legge (lentamente) dal buffer, quindi scoppierà di nuovo per riempire il buffer. Per un download di grandi dimensioni, la media è di 10 byte/sec dal telecomando, ma per un download di dimensioni ridotte lo stai consumando lentamente, senza alcuna differenza nell'attività di rete. Per limitare l'attività netta, vedere https://unix.stackexchange.com/questions/28198/how-to-limit-network-bandwidth –

11

I pacchetti di terze parti hanno wrapper convenienti. Ma se sei interessato a come funzionano le cose sotto il cofano, è abbastanza facile.

package main 

import (
    "io" 
    "net/http" 
    "os" 
    "time" 
) 

var datachunk int64 = 500  //Bytes 
var timelapse time.Duration = 1 //per seconds 

func main() { 
    responce, _ := http.Get("http://google.com") 
    for range time.Tick(timelapse * time.Second) { 
     _, err :=io.CopyN(os.Stdout, responce.Body, datachunk) 
     if err!=nil {break} 
    } 
} 

Niente di magico.