golang实现ftp实时传输文件 - Go语言中文社区

golang实现ftp实时传输文件


一、项目简介

本项目主要实现的功能是ftp客户端不断地将xml文件和jpg文件实时地上传到服务器,当然也可以是其他格式的文件。每当ftp客户端取到一个文件之后,将文件上传到服务器后,然后将其删除。项目实现可配置,如果开发者有类似的需求,只需要修改配置文件就可以使用本项目去完成上传文件的功能。本项目打日志是按照当天时间来生成日志文件,每天每一种类型的日志只打一个文件。

二、项目结构图片

这里写图片描述

三、项目代码

config配置中的代码

config.ini

[path]
   xml_path         = D:\dian\out\        # xml文件所在的路径
   img_path         = D:\dian\out\wave\  # 图片文件所在路径
[ftp]
   ftpfile_path     = D:\Itudou             # 在服务器上的文件存储路径
   ftp_server_ip    = 192.168.56.1           # ftp服务器的IP
   ftp_server_port  = 21                     # ftp服务器的端口
   ftp_server_name  = 20123762               # ftp服务器的用户名
   ftp_server_pwd   = 123456                 # ftp服务器的密码
   local_ip         = 192.168.56.1           # 本地主机的IP
   local_port       = 80                     #本地主机端口
   comm_way         = udp                    #ftp的通信方式
[file]
   file_img         =.jpg                    #文件后缀为img
   file_xml         =.xml                    #文件后缀为xml
   log_print        = ture                   #是否打日志,生产环境上不打日志,在调式程序的时候使用
读配置文件的代码

daos_config.go

package daosconfig

import (
    "bufio"
    "io"
    "os"
    "strings"
)

type Config struct {
    Mymap  map[string]string
    strcet string
}

func (c *Config) InitConfig(path string) {
    c.Mymap = make(map[string]string)
    f, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer f.Close()
    r := bufio.NewReader(f)
    for {
        b, _, err := r.ReadLine()
        if err != nil {
            if err == io.EOF {
                break
            }
            panic(err)
        }
        s := strings.TrimSpace(string(b))
        if strings.Index(s, "#") == 0 {
            continue
        }
        n1 := strings.Index(s, "[")
        n2 := strings.LastIndex(s, "]")
        if n1 > -1 && n2 > -1 && n2 > n1+1 {
            c.strcet = strings.TrimSpace(s[n1+1 : n2])
            continue
        }
        if len(c.strcet) == 0 {
            continue
        }
        index := strings.Index(s, "=")
        if index < 0 {
            continue
        }
        frist := strings.TrimSpace(s[:index])
        if len(frist) == 0 {
            continue
        }
        second := strings.TrimSpace(s[index+1:])

        pos := strings.Index(second, "t#")
        if pos > -1 {
            second = second[0:pos]
        }
        pos = strings.Index(second, " #")
        if pos > -1 {
            second = second[0:pos]
        }
        pos = strings.Index(second, "t//")
        if pos > -1 {
            second = second[0:pos]
        }
        pos = strings.Index(second, " //")
        if pos > -1 {
            second = second[0:pos]
        }
        if len(second) == 0 {
            continue
        }
        key := c.strcet + "=" + frist
        c.Mymap[key] = strings.TrimSpace(second)
    }
}

func (c Config) Read(node, key string) string {
    key = node + "=" + key
    v, found := c.Mymap[key]
    if !found {
        return ""
    }
    return v
}
ftp上传文件核心代码

daos_ftp.go

package daosftp

import (
    "fmt"
    "net"
    "os"
    "strings"
    ftp "github.com/ftp"
    "io/ioutil"
    "regexp"
    "path/filepath"
    cfg "bjdaos_tool/pkg/daosconfig"
    "bjdaos_tool/pkg/env"
    "bjdaos_tool/pkg/daoslog"
)

func getListDir(dirPth string) (files []string,files1 []string, err error) {
    dir, err := ioutil.ReadDir(dirPth)
    if err != nil {
        return nil,nil, err
    }
    PthSep := string(os.PathSeparator)
    for _, fi := range dir {
        if fi.IsDir() {
            files1 = append(files1, dirPth+PthSep+fi.Name())
            getListDir(dirPth + PthSep + fi.Name())
        }else{
            files = append(files, dirPth+PthSep+fi.Name())
        }
    }
    return files,files1, nil
}

func GetAllFileName(path string, str string) (int, []string ) {
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    logPrint := ftpConfig.Read("file", "log_print")
    files, _, err := getListDir(path)
    if err != nil {
        daoslog.WriteLog(logPrint, "System","get file path err")
    }
    fileLen := len(files)
    fileSlice := make([]string,0, fileLen)
    suffix1 := ftpConfig.Read("file", "file_img")
    suffix2 := ftpConfig.Read("file", "file_xml")
    reg_front := regexp.MustCompile("\d{8}")
    reg_end := regexp.MustCompile("\d{14}")
    if str == suffix1{
        for i := 0; i < fileLen; i++{
            data_front := reg_front.FindString(files[i])
            date_end := reg_end.FindString(files[i])
            imgName := data_front + "_" + date_end + str
            fileSlice = append(fileSlice, imgName)
        }
    }else if str == suffix2 {
        for i := 0; i < fileLen; i++{
            data_front := reg_front.FindString(files[i])
            date_end := reg_end.FindString(files[i])
            imgName := data_front + "_" + date_end + str
            fileSlice = append(fileSlice, imgName)
        }
    }
    return fileLen, fileSlice
}

func getLocalIpAddr() string {
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    logPrint := ftpConfig.Read("file", "log_print")
    network := ftpConfig.Read("ftp", "comm_way")
    ip := ftpConfig.Read("ftp", "local_ip")
    port := ftpConfig.Read("ftp", "local_port")
    address := ip + ":" + port
    conn, err := net.Dial(network, address)
    if err != nil {
        daoslog.WriteLog(logPrint, "System", "get local ip address err")
        return "127.0.0.1"
    }
    defer conn.Close()
    return strings.Split(conn.LocalAddr().String(), ":")[0]
}

func ftpUploadFile(ftpserver, ftpuser, pw, localFile, remoteSavePath, saveName string) {
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    logPrint := ftpConfig.Read("file", "log_print")
    ftpfile_path := ftpConfig.Read("ftp", "ftpfile_path")
    ftp, err := ftp.Connect(ftpserver)
    if err != nil {
        daoslog.WriteLog(logPrint, "System", "connect err")
    }
    err = ftp.Login(ftpuser, pw)
    if err != nil {
        daoslog.WriteLog(logPrint, "System", "Login err")
    }
    ftp.ChangeDir(ftpfile_path)
    dir, err := ftp.CurrentDir()
    ftp.MakeDir(remoteSavePath)
    ftp.ChangeDir(remoteSavePath)
    dir, _ = ftp.CurrentDir()
    daoslog.WriteLog(logPrint, "System", dir)
    file, err := os.Open(localFile)
    if err != nil {
        daoslog.WriteLog(logPrint, "System", "Open err")
    }
    defer file.Close()
    err = ftp.Stor(saveName, file)
    if err != nil {
        daoslog.WriteLog(logPrint, "System", "Stor err")
    }
    ftp.Logout()
    ftp.Quit()
    logcotent := fmt.Sprintf("%s:%s","success upload file",localFile)
    daoslog.WriteLog(logPrint, "System", logcotent)
}

func RemoveFile(filePath string, fileName string){
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    logPrint := ftpConfig.Read("file", "log_print")
    err := os.Remove(filePath + fileName)
    if err != nil {
        daoslog.WriteLog("false", "System", "file remove err!")
    } else {
        logcotent := fmt.Sprintf("%s:%s","file remove OK!",fileName)
        daoslog.WriteLog(logPrint, "System", logcotent)
    }
}

func SendXmlFileToFtpServer(filePath string, fileType string) {
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    logPrint := ftpConfig.Read("file", "log_print")
    flen, fileName := GetAllFileName(filePath, fileType)
    serverIp := getLocalIpAddr()
    ftpserverip := ftpConfig.Read("ftp", "ftp_server_ip")
    ftpPort := ftpConfig.Read("ftp", "ftp_server_port")
    ftpuser := ftpConfig.Read("ftp", "ftp_server_name")
    pw := ftpConfig.Read("ftp", "ftp_server_pwd")
    ftpserver := ftpserverip + ":" + ftpPort
    filepath.Walk(filePath, func(path string, f os.FileInfo, err error) error {
        if f == nil {
            return err
        }
        if f.IsDir() {
            return nil
        }
        for i := 0; i < flen; i++{
            if f.Name() == fileName[i] {
                logcotent := fmt.Sprintf("path=",path)
                daoslog.WriteLog(logPrint, "System", logcotent)
                pathFields := strings.Split(path, "\")
                var domainName string
                if len(pathFields) > 3 {
                    domainName = pathFields[len(pathFields)-3]
                }
                ftpUploadFile(ftpserver, ftpuser, pw, path, domainName, serverIp+"_"+fileName[i])
                RemoveFile(filePath, fileName[i])
            }
        }
        return nil
    })
}

func SendJpgFileToFtpServer(filePath string, fileType string) {
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    logPrint := ftpConfig.Read("file", "log_print")
    flen, fileName := GetAllFileName(filePath, fileType)
    serverIp := getLocalIpAddr()
    ftpserverip := ftpConfig.Read("ftp", "ftp_server_ip")
    ftpPort := ftpConfig.Read("ftp", "ftp_server_port")
    ftpuser := ftpConfig.Read("ftp", "ftp_server_name")
    pw := ftpConfig.Read("ftp", "ftp_server_pwd")
    ftpserver := ftpserverip + ":" + ftpPort
    filepath.Walk(filePath, func(path string, f os.FileInfo, err error) error {
        if f == nil {
            return err
        }
        if f.IsDir() {
            return nil
        }
        for i := 0; i < flen; i++{
            if f.Name() == fileName[i] {
                logcotent := fmt.Sprintf("path=",path)
                daoslog.WriteLog(logPrint, "System", logcotent)
                pathFields := strings.Split(path, "\")
                var domainName string
                if len(pathFields) > 3 {
                    domainName = pathFields[len(pathFields)-3]
                }
                ftpUploadFile(ftpserver, ftpuser, pw, path, domainName, serverIp+"_"+fileName[i])
                RemoveFile(filePath, fileName[i])
            }
        }
        return nil
    })
}
打日志的代码

daos_log.go

package daoslog

import (
    "fmt"
    "log"
    "os"
    "github.com/golang/glog"
    "time"
    "bjdaos_tool/pkg/env"
)

func WriteLog(islog,  logtype , errcontent string) {
    if islog == "false" {
        return
    }
    if logtype != "Info" && logtype!= "Debug" && logtype!= "Error" && logtype != "System"  {
        glog.Error("this is not a logtype ")
        return
    }
    data := time.Now().Format("20060102")
    logPath := env.GetConLogPath()
    logFilea := logPath + "\" + data+"_"+ logtype+".log"
    errcontent = "[" +errcontent + "]"

    logFile, err := os.OpenFile(logFilea, os.O_RDWR | os.O_CREATE, 0777)
    if err != nil {
        fmt.Printf("open file error=%srn", err.Error())
        os.Exit(-1)
    }
    logger := log.New(logFile, "{"+logtype+"} ", log.Ldate | log.Ltime | log.Lshortfile)
    logger.Println(errcontent)
}
路径处理代码

daos-evn.go

package env
import (
    "os"
    "runtime"
)

var ostype = runtime.GOOS

func GetProjectPath() string{
    var projectPath string
    projectPath, _ = os.Getwd()
    return projectPath
}

func GetConfigPath() string{
    path := GetProjectPath()
    if ostype == "windows"{
        path = path + "\" + "config\"
    }else if ostype == "linux"{
        path = path +"/" + "config/"
    }
    return  path
}

func GetConLogPath() string{
    path := GetProjectPath()
    if ostype == "windows"{
        path = path + "\log\"
    }else if ostype == "linux"{
        path = path + "/log/"
    }
    return  path
}

四、总结

主函数:
main.go

package main

import (
    "bjdaos_tool/pkg/daosftp"
    "bjdaos_tool/pkg/env"
    cfg "bjdaos_tool/pkg/daosconfig"
)

func main(){
    configPath := env.GetConfigPath()
    ftpConfig := new(cfg.Config)
    ftpConfig.InitConfig(configPath + "\config.ini")
    xml_path := ftpConfig.Read("path", "xml_path")
    img_path := ftpConfig.Read("path", "img_path")
    file_img := ftpConfig.Read("file", "file_img")
    file_xml := ftpConfig.Read("file", "file_xml")
    for{
        daosftp.SendXmlFileToFtpServer(xml_path, file_xml)
        daosftp.SendJpgFileToFtpServer(img_path, file_img)
    }
}

本项目依赖包:
这里写图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/jiang_xinxing/article/details/72083981
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2019-09-04 16:11:04
  • 阅读 ( 919 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢