go程序 ftp上传(可直接用)

package main
import (
"fmt"
"os"
"net"
    // "sync" 
    "path"
    "time" 
    "os/exec"
"strconv"
"strings"
    // "runtime"
"io/ioutil"
    "encoding/json"
    "path/filepath"
)

type FTP struct {
host string
port int
user string
passwd string
pasv int
cmd string
Code int
Message string
Debug bool
stream []byte
conn net.Conn
dataConn net.Conn
// Error os.Error
}




type Config struct {
    Host string  // ip
    Port int    // 端口
    User string  // 用户名
    Passwd    string    // 密码
    LocalDir    string    // 本地位置
    LocalFile string    // 本地文件
    FtpDir    string    // ftp位置
    Vresion string // 版本
    Pf string // 平台
Debug bool
}

var config Config
var zipModeSize = 1024 // 压缩模式大小
// var waitgroup sync.WaitGroup  // 记录进程处理结束
 
 func main() {
var ftp = new(FTP)
var FlaConfigPath = "./ftp_config.json"
    if !checkFileIsExist(FlaConfigPath) {
        fmt.Println("当前目录缺少文件: config.json")
        return 
     }
    readConfig(FlaConfigPath)
// svn_up_dir(config.LocalDir)
    ftp.Debug = config.Debug
    // connect
    ftp.Connect(config.Host, config.Port)
    // login
    ftp.Login(config.User, config.Passwd)
    // login failure
    if ftp.Code == 530 {
        fmt.Println("error: login failure")
        os.Exit(-1)
    }
    // pwd
    ftp.Pwd()
    fmt.Println("code:", ftp.Code, ", message:", ftp.Message)

     resourceDir := config.FtpDir + "resource/"
     ftp.debugInfo("config.Pf:" + config.Pf)
     if config.Pf != "" {
PfDir := config.LocalDir + config.Pf + "/"
ftp.ftp_request(PfDir, "", config.FtpDir)
     }else{
ftp.Mkd(resourceDir)
     }
     if config.Vresion == "" {
ftp.ftp_request(config.LocalDir + "resource/" , config.LocalFile, resourceDir)
     } else {
  VresionDir := resourceDir + config.Vresion + "/"
  FilelistDir := resourceDir + "filelist/"
ftp.Mkd(VresionDir)
ftp.ftp_request(config.LocalDir + "resource/" + config.Vresion + "/" , config.LocalFile, VresionDir)
ftp.Mkd(FilelistDir)
ftp.ftp_request(config.LocalDir + "resource/filelist/", config.Vresion + ".json", FilelistDir)
     }
    // quit
    ftp.Quit()
}

// 更新目录内容 
func svn_up_dir(pathDir string) {
    cmd := exec.Command("/bin/sh", "-c", `svn up`)
    cmd.Dir = string_remove(pathDir) 
    out, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Println(err, "svn_up_dir err: /n", string(out))
        os.Exit(3)
    }
    fmt.Println("svn_up >>>>>>>> ", pathDir)
}

func (ftp *FTP) ftp_request(dirPath string, fileName string, ftpDirPath string) {
    // runtime.GOMAXPROCS(runtime.NumCPU())
    dirPath = strings.Replace(dirPath, "\\", "/", -1)
toDirPath := dirPath + fileName
fmt.Println("开始上传文件夹内容 ==>> ", toDirPath)
    var calcTime = time.Now().Unix()
    var toTime = time.Now().Unix()
    var toNum = 0
    var topNum = 0
    var minNum = 9999999
    var totleNum = 0
    var calcNumber = 1
filepath.Walk(toDirPath, func(path1 string, file os.FileInfo, err error) error {
        if ( file == nil ) {return err}
        if strings.Index(path1, ".svn") != -1 { return nil}          // 过滤svn文件 
        toTime = time.Now().Unix()
        if (toTime - calcTime) > 10 {
            if topNum < toNum {
              topNum = toNum
            }
            if toNum < minNum && 0 < toNum {
              minNum = toNum
            }
            totleNum += toNum
            fmt.Println(calcNumber ,"个 10s 上传了:", toNum, " 条数据, 当前完成数量:", totleNum)
            calcNumber ++ 
            calcTime = toTime
            toNum = 0
        }
        toNum ++
// ftp.debugInfo("ftp_request >> " + path1)
        path1 = strings.Replace(path1, "\\", "/", -1)
        path2 := strings.Replace(path1, dirPath, ftpDirPath, -1)
        // path2 = strings.Replace(path2, "\\", "/", -1)
        if file.IsDir() {
    ftp.Mkd(path2)
            return nil
        }
    ftp.Request("TYPE I")
    byteFile, _ := ioutil.ReadFile(path1)
    // if len(byteFile) >= zipModeSize {
    // ftp.Request("MODE C")
    // }
        // waitgroup.Add(1) //每创建一个goroutine,就把任务队列中任务的数量+1
    ftp.Stor(path2, byteFile)
        return nil
    })   
totleNum = totleNum + toNum
    // waitgroup.Wait() //Wait()这里会发生阻塞,直到队列中所有的任务结束就会解除阻塞
    fmt.Println(dirPath, "\r\n ==>> 处理 最高", topNum, ">> 最低", minNum, ">> 平均", totleNum/calcNumber, " \r\n ==>> 上传时间:", calcNumber * 10,"s >> 上传文件总数", totleNum)
}

func (ftp *FTP) debugInfo(s string) {
if ftp.Debug {
fmt.Println(s)
}
}
func (ftp *FTP) Connect(host string, port int) {
addr := fmt.Sprintf("%s:%d", host, port)
ftp.conn, _ = net.Dial("tcp", addr)
ftp.Response()
ftp.host = host
ftp.port = port
}
 
func (ftp *FTP) Login(user, passwd string) {
ftp.Request("USER " + user)
ftp.Request("PASS " + passwd)
ftp.user = user
ftp.passwd = passwd
}
 
func (ftp *FTP) Response() (code int, message string) {
ret := make([]byte, 1024)
n, _ := ftp.conn.Read(ret)
msg := string(ret[:n])
code, _ = strconv.Atoi(msg[:3])
message = msg[4 : len(msg)-2]
ftp.debugInfo("<*cmd*> " + ftp.cmd)
ftp.debugInfo(fmt.Sprintf("<*code*> %d", code))
ftp.debugInfo("<*message*> " + message)
return
}
func (ftp *FTP) Request(cmd string) {
ftp.conn.Write([]byte(cmd + "\r\n"))
ftp.cmd = cmd
ftp.Code, ftp.Message = ftp.Response()
if cmd == "PASV" { // 被动监听连接
start, end := strings.Index(ftp.Message, "("), strings.Index(ftp.Message, ")")
s := strings.Split(ftp.Message[start:end], ",")
l1, _ := strconv.Atoi(s[len(s)-2])
l2, _ := strconv.Atoi(s[len(s)-1])
ftp.pasv = l1*256 + l2
}
if (cmd != "PASV") && (ftp.pasv > 0) {
ftp.Message = newRequest(ftp.host, ftp.pasv, ftp.stream)
ftp.debugInfo("<*response*> " + ftp.Message)
ftp.pasv = 0
ftp.stream = nil
ftp.Code, _ = ftp.Response()
}
}
 
func (ftp *FTP) Pasv() {
ftp.Request("PASV")
}
 
func (ftp *FTP) Pwd() {
ftp.Request("PWD")
}
 
func (ftp *FTP) Cwd(path string) {
ftp.Request("CWD " + path)
}
 
func (ftp *FTP) Mkd(path string) {
ftp.Request("MKD " + path)
}
 
func (ftp *FTP) Size(path string) (size int) {
ftp.Request("SIZE " + path)
size, _ = strconv.Atoi(ftp.Message)
return
}
 
func (ftp *FTP) List() {
ftp.Pasv()
ftp.Request("LIST")
}
 
func (ftp *FTP) Stor(file string, data []byte) {
ftp.Pasv()
if data != nil {
ftp.stream = data
}
ftp.Request("STOR " + file)
    // waitgroup.Done() //任务完成,将任务队列中的任务数量-1,其实.Done就是.Add(-1) 
}
 
func (ftp *FTP) Quit() {
ftp.Request("QUIT")
ftp.conn.Close()
}
 
// new connect to FTP pasv port, return data
func newRequest(host string, port int, b []byte) string {
conn, _ := net.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
defer conn.Close()
if b != nil {
conn.Write(b)
return "OK"
}
ret := make([]byte, 4096)
n, _ := conn.Read(ret)
return string(ret[:n])
}
 
// 读取配置
func readConfig(path string) {
    bytes, _ := ioutil.ReadFile(path)
    err := json.Unmarshal(bytes, &config)
    if err != nil {  
        fmt.Println("error in translating,", err.Error())
        return
    }
}

/** 
 * 判断文件是否存在  存在返回 true 不存在返回false
 */
func checkFileIsExist(filename string) (bool) {
    var exist = true;
    if _, err := os.Stat(filename); os.IsNotExist(err) {
       exist = false;
    }
    return exist;
}

// 获得文件夹路径        去除路径文件部分
func string_remove(str string)(file string){
    return path.Dir(str)
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值