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)
}
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)
}