校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > golang實現的文件上傳下載小工具

golang實現的文件上傳下載小工具

熱門標簽:鄭州智能語音電銷機器人價格 仙桃400電話辦理 寧波語音外呼系統公司 宿遷便宜外呼系統代理商 湛江crm外呼系統排名 地圖標注免費定制店 重慶慶云企業400電話到哪申請 上海極信防封電銷卡價格 不封卡外呼系統

前言

雖然現在文件上傳下載工具多如牛毛,比如http、ftp、sftp、scp等方案都可以用于文件傳輸,但都是需要安裝服務器甚至客戶端。
有一種場景是我只需要臨時上傳或下載一個文件,完了就不用服務器運行了,如果使用那些文件傳輸工具,不光安裝麻煩,開啟關閉也惱火額。
因此才想搞小工具,不過Python愛好者可以用python -m http.server 8080 --bind 192.168.1.100開啟文件服務器,對我來說還是麻煩。
已經上傳到【Github】,隨意鑒賞。

源碼鑒賞

模擬一個http服務器,通過curl和wget命令作為客戶端實現文件的上傳下載功能。
只是實現一個小工具,所以沒必要使用http庫了,我也試過用http庫來完成相同的功能,發現很多東西都用不上。
上傳和下載文件加入了進度顯示,方便知道上傳和下載進度。本來想實現斷點續傳功能,但比較懶,不想弄,原理很簡單。
想想還是把認證授權加上去,不然太不安全了,命令行更新了使用用戶名和密碼方式的上傳和下載。

package main
 
import (
  "bufio"
  "encoding/base64"
  "errors"
  "fmt"
  "io"
  "net"
  "net/url"
  "os"
  "path/filepath"
  "strconv"
  "strings"
  "unsafe"
)
 
func main() {
  if len(os.Args) != 3 {
    fmt.Printf(`usage: %s ip:port user:pass
 
get file:
 wget --auth-no-challenge --user=user --password=pass --content-disposition "http://ip:port?/home/tmp.txt"
 curl -u user:pass -OJ "http://ip:port?/home/tmp.txt"
post file:
 wget -qO - --auth-no-challenge --user=user --password=pass --post-file=C:\tmp.txt "http://ip:port?/home/tmp.txt"
 curl -u user:pass --data-binary @C:\tmp.txt "http://ip:port?/home/tmp.txt"
`, os.Args[0])
    return
  }
  addr, err := net.ResolveTCPAddr("tcp", os.Args[1])
  if err != nil {
    panic(err)
  }
  ser, err := net.ListenTCP("tcp", addr)
  if err != nil {
    panic(err)
  }
 
  fmt.Printf("Listen: [%s]\n", addr)
  authStr = "Basic " + base64.StdEncoding.EncodeToString([]byte(os.Args[2]))
  for {
    ln, err := ser.AcceptTCP()
    if err != nil {
      panic(err)
    }
    go func(l *net.TCPConn) {
      err := handleFile(l)
      if err != nil {
        respData(l, err.Error())
      }
      l.Close()
    }(ln)
  }
}
 
const (
  maxMemory = 10  20 // 緩存10MB
  respMsg  = "HTTP/1.1 200 OK\r\nContent-Type:text/plain;charset=utf-8\r\nContent-Disposition:attachment;filename=resp.txt\r\nContent-Length:%d\r\n\r\n%s"
  getHeader = "HTTP/1.1 200 OK\r\nContent-Type:application/octet-stream\r\nContent-Disposition:attachment;filename=%s\r\nContent-Length:%d\r\nContent-Transfer-Encoding:binary\r\n\r\n"
)
 
var authStr string // 授權信息
 
func respData(w io.Writer, data string) {
  msg := data + "\r\n"
  fmt.Fprintf(w, respMsg, len(msg), msg)
}
 
func handleFile(l *net.TCPConn) error {
  br := bufio.NewReaderSize(l, maxMemory)
  method, path, length, err := getHeaderMsg(br)
  if err != nil {
    return err
  }
  fmt.Printf("[%s - %s - %d]\n", method, path, length)
 
  if method == "GET" {
    return httpGetFile(path, l, length)
  }
  err = httpPostFile(path, br, length)
  if err != nil {
    return err
  }
  respData(l, "post ok")
  return nil
}
 
// 內存復用,更快速,省內存
func bytesToString(b []byte) string {
  return *(*string)(unsafe.Pointer(b))
}
 
func getHeaderMsg(r *bufio.Reader) (string, string, int64, error) {
  // 讀取第一行,提取有用信息
  line, _, err := r.ReadLine()
  if err != nil {
    return "", "", 0, err
  }
  header := strings.Fields(bytesToString(line))
  if len(header)  3 { // 首行至少3列數據
    return "", "", 0, errors.New("header error")
  }
  method, path := header[0], ""
 
  s := strings.Index(header[1], "?")
  if s >= 0 {
    path, _ = url.QueryUnescape(header[1][s+1:])
  }
  if path == "" { // ?號后面就是文件路徑,需要解碼url一下
    return "", "", 0, errors.New("path error")
  }
 
  var length int64
  if method == "GET" {
    fi, err := os.Stat(path)
    if err != nil {
      return "", "", 0, err
    }
    length = fi.Size() // GET請求提前得到文件大小
  } else if method != "POST" {
    return "", "", 0, errors.New(method + " not support")
  }
 
  var authCheck string
  for {
    line, _, err = r.ReadLine()
    if err != nil {
      return "", "", 0, err
    }
    if len(line) == 0 {
      break // 遇到空行,之后為請求體
    }
    header = strings.Split(bytesToString(line), ":")
    if len(header) == 2 { // 頭部[key: val]解析
      header[0] = strings.ToLower(strings.TrimSpace(header[0]))
      header[1] = strings.TrimSpace(header[1])
      if method == "POST"  header[0] == "content-length" {
        length, _ = strconv.ParseInt(header[1], 10, 64)
      } else if header[0] == "authorization" {
        authCheck = header[1]
      }
    }
  }
  if authCheck != authStr {
    return "", "", 0, errors.New("authorization error")
  }
  return method, path, length, nil
}
 
func httpPostFile(path string, r io.Reader, length int64) error {
  fw, err := os.Create(path)
  if err != nil {
    return err
  }
  defer fw.Close()
  pr := newProgress(r, length)
  _, err = io.CopyN(fw, pr, length)
  pr.Close()
  return err
}
 
func httpGetFile(path string, w io.Writer, size int64) error {
  fr, err := os.Open(path)
  if err != nil {
    return err
  }
  defer fr.Close()
  fmt.Fprintf(w, getHeader, filepath.Base(path), size)
  pr := newProgress(fr, size)
  _, err = io.Copy(w, pr)
  pr.Close()
  return err
}
 
type progress struct {
  r  io.Reader
  cnt int64
  rate chan int64
}
 
func newProgress(r io.Reader, size int64) io.ReadCloser {
  p := progress{r: r, rate: make(chan int64)}
  // 之所以這樣做進度,是因為打印耗性能,因此在協程中打印進度
  // 在處理數據中用非阻塞方式往chan中傳處理字節數
  go func(rate -chan int64, all int64) {
    for cur := range rate {
      fmt.Printf("\rhandle:%4d%%", cur*100/all)
    }
    fmt.Printf("\rhandle: 100%%\r\n\r\n")
  }(p.rate, size)
  return p
}
 
func (p *progress) Read(b []byte) (int, error) {
  n, err := p.r.Read(b)
  p.cnt += int64(n)
  select { // 非阻塞方式往chan中寫數據
  case p.rate - p.cnt:
  default:
  }
  return n, err
}
 
func (p *progress) Close() error {
  close(p.rate) // 關閉chan,通知打印協程退出
  return nil
}

食用方法

執行UpDownFile-h可以查看幫助文檔,里面有wget和curl上傳和下載文件的命令,方便忘記命令的時候copy一下下。
工具雖小,但確實解決了我個人的臨時上傳下載文件需求,再也不用到處安裝各種服務器咯,爽爽噠。

usage: UpDownFile ip:port
 
get file:
 wget --auth-no-challenge --user=user --password=pass --content-disposition "http://ip:port?/home/tmp.txt"
 curl -u user:pass -OJ "http://ip:port?/home/tmp.txt"
post file:
 wget -qO - --auth-no-challenge --user=user --password=pass --post-file=C:\tmp.txt "http://ip:port?/home/tmp.txt"
 curl -u user:pass --data-binary @C:\tmp.txt "http://ip:port?/home/tmp.txt"

以上就是golang實現的文件上傳下載小工具的詳細內容,更多關于golang實現文件上傳下載的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • golang語言實現的文件上傳與文件下載功能示例
  • Golang實現異步上傳文件支持進度條查詢的方法
  • Golang+Android基于HttpURLConnection實現的文件上傳功能示例
  • golang簡單獲取上傳文件大小的實現代碼
  • Golang實現http文件上傳小功能的案例

標簽:安康 海南 物業服務 遼寧 西雙版納 電子產品 青海 儋州

巨人網絡通訊聲明:本文標題《golang實現的文件上傳下載小工具》,本文關鍵詞  golang,實現,的,文件,上傳下載,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《golang實現的文件上傳下載小工具》相關的同類信息!
  • 本頁收集關于golang實現的文件上傳下載小工具的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    在线成人高清不卡| 亚洲欧美日韩精品久久久久| 国产日本欧美一区二区| 国产精品一区二区久久不卡 | 99久久精品一区| 欧美激情一区二区三区四区| 99久久国产综合精品麻豆| 亚洲一区在线观看免费| 欧美一级黄色片| 成人久久18免费网站麻豆 | 欧美精品一区二区久久久| 国产精品99久久久久久久女警 | 中文字幕一区免费在线观看| 欧美日韩综合不卡| 国产精品亚洲第一区在线暖暖韩国| 亚洲欧洲无码一区二区三区| 欧美挠脚心视频网站| 国产成人福利片| 午夜精品久久久久久久久久| 久久久精品人体av艺术| 欧美日本一区二区| 91丨九色porny丨蝌蚪| 老司机免费视频一区二区| 亚洲精品成人在线| 欧美经典一区二区三区| 欧美一级欧美三级| 欧洲一区在线观看| av电影天堂一区二区在线| 日本欧美肥老太交大片| 一区二区三区四区av| 国产欧美综合色| 久久综合色鬼综合色| 日韩一区二区三区高清免费看看| 在线视频中文字幕一区二区| 成人伦理片在线| 成人小视频在线| 精品一区二区三区在线观看国产| 亚洲成av人片| 亚洲一区二区三区小说| 国产精品不卡视频| 中文字幕在线视频一区| 国产欧美精品国产国产专区 | 国产精品系列在线| 久久婷婷久久一区二区三区| 精品噜噜噜噜久久久久久久久试看| 欧美日韩一区二区在线观看视频| 91丨porny丨蝌蚪视频| 成人av网站大全| av在线这里只有精品| 成人激情黄色小说| 成人免费高清在线观看| 成人免费看的视频| 91亚洲资源网| 在线日韩国产精品| 欧美日韩成人综合在线一区二区| 欧美性猛交一区二区三区精品| 色婷婷久久久综合中文字幕| 欧美日韩性生活| 欧美一区二区视频免费观看| 欧美成人高清电影在线| 国产偷国产偷亚洲高清人白洁| 久久久久久夜精品精品免费| 国产日韩欧美不卡在线| 国产精品美女久久久久aⅴ国产馆| 国产欧美一区二区在线| 亚洲欧美在线视频观看| 亚洲丝袜自拍清纯另类| 亚洲高清不卡在线观看| 美女视频一区二区三区| 成人av在线观| 欧美日本国产视频| 久久久久久久久一| 有码一区二区三区| 日本一区中文字幕| 国产aⅴ综合色| 欧美三级日韩三级国产三级| 日韩欧美在线1卡| 国产精品久久久久久久久免费丝袜 | 亚洲精品欧美专区| 日本中文字幕一区二区视频| 国精产品一区一区三区mba视频| 从欧美一区二区三区| 欧美色欧美亚洲另类二区| 精品国产乱码久久久久久夜甘婷婷 | 国产自产视频一区二区三区| 91免费看视频| 欧美不卡一二三| 亚洲品质自拍视频| 久久国产精品区| 色婷婷国产精品久久包臀| 日韩欧美一级二级| 亚洲乱码中文字幕| 国产成人午夜电影网| 欧美日韩和欧美的一区二区| 欧美国产成人精品| 日韩电影在线一区二区三区| 成人黄色av电影| 日韩欧美区一区二| 亚洲国产一区二区三区| 成a人片亚洲日本久久| 欧美成人一级视频| 亚洲亚洲精品在线观看| 成人午夜伦理影院| 精品国产乱码久久| 美国毛片一区二区三区| 91高清视频免费看| 亚洲色图视频免费播放| 国产91在线观看| 久久综合狠狠综合久久激情| 日本在线不卡视频| 欧美高清dvd| 亚洲国产日韩av| 色域天天综合网| 国产精品久久久久一区二区三区| 久久精品国产精品亚洲精品| 久久精品国产亚洲高清剧情介绍 | 欧美午夜寂寞影院| 国产精品婷婷午夜在线观看| 精品在线你懂的| 日韩欧美成人一区二区| 日本女人一区二区三区| 欧美一二三在线| 青青草国产精品97视觉盛宴| 欧美精品在线一区二区| 亚洲mv在线观看| 欧美一级生活片| 激情六月婷婷久久| 亚洲精品一区在线观看| 国产中文一区二区三区| 久久综合九色综合久久久精品综合| 另类小说综合欧美亚洲| 精品久久久久久久久久久久久久久久久| 五月天精品一区二区三区| 67194成人在线观看| 天天色天天爱天天射综合| 91精品国产全国免费观看| 久久国产免费看| 欧美国产禁国产网站cc| 色婷婷综合视频在线观看| 亚洲一区二区欧美激情| 欧美一区二区三区电影| 国产乱子伦视频一区二区三区| 自拍av一区二区三区| 91偷拍与自偷拍精品| 亚洲高清免费观看高清完整版在线观看| 欧美日韩高清一区二区| 久久成人麻豆午夜电影| 中日韩av电影| 欧美三级一区二区| 久久99精品国产麻豆婷婷| 国产亚洲精品超碰| 在线精品国精品国产尤物884a| 天堂在线亚洲视频| 久久久777精品电影网影网| 一本大道久久a久久综合| 日本不卡的三区四区五区| 国产欧美一二三区| 欧美另类变人与禽xxxxx| 国产精品123区| 亚洲国产va精品久久久不卡综合| 日韩欧美一区在线观看| av一二三不卡影片| 蜜桃久久久久久久| 日韩美女精品在线| 久久一夜天堂av一区二区三区| 97精品视频在线观看自产线路二 | 亚洲成人中文在线| 欧美国产日韩亚洲一区| 欧美午夜片在线观看| 国产一区二区在线看| 亚洲高清免费观看| 国产精品嫩草99a| 精品成人a区在线观看| 欧美天堂一区二区三区| 粉嫩一区二区三区在线看| 日韩不卡手机在线v区| 亚洲人成网站影音先锋播放| 精品国产免费视频| 欧美精品久久天天躁| 色婷婷国产精品| 99免费精品在线观看| 国产激情视频一区二区在线观看| 日韩av一区二区三区| 伊人一区二区三区| 中文字幕制服丝袜成人av| 日本一区二区三区在线不卡| 2022国产精品视频| 日韩欧美亚洲国产另类| 欧美久久高跟鞋激| 欧美视频第二页| 欧美艳星brazzers| 91麻豆成人久久精品二区三区| 国产麻豆欧美日韩一区| 麻豆一区二区三| 免费一区二区视频| 蜜臀av一区二区在线免费观看| 亚洲aaa精品| 日韩中文字幕区一区有砖一区| 亚洲一二三区不卡| 偷窥国产亚洲免费视频|